/* ════════════════════════════════════════════════════════════════════
   Fonts — self-hosted.

   Served from /static/fonts rather than Google Fonts, so the account area has
   no third-party request on every page: no dependency on Google being up, no
   IP address handed to them for each visitor, and it works behind a firewall.
   Both faces are OFL (licences ship beside the files). Only the weights the
   templates actually use are shipped; the browser maps the rest to the nearest.
   ──────────────────────────────────────────────────────────────────── */
@font-face {
  font-family: "Archivo";
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url("/static/fonts/Archivo-Regular.ttf") format("truetype");
}
@font-face {
  font-family: "Archivo";
  font-weight: 600 700;   /* SemiBold covers the bold headings too */
  font-style: normal;
  font-display: swap;
  src: url("/static/fonts/Archivo-SemiBold.ttf") format("truetype");
}
@font-face {
  font-family: "Martian Mono";
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  src: url("/static/fonts/MartianMono-Regular.ttf") format("truetype");
}
@font-face {
  font-family: "Martian Mono";
  font-weight: 500 600;
  font-style: normal;
  font-display: swap;
  src: url("/static/fonts/MartianMono-Medium.ttf") format("truetype");
}

/* ════════════════════════════════════════════════════════════════════
   MERIDIAN — account area

   The same design system as the marketing site, hand-rolled. The site gets
   these tokens from Tailwind's @theme in app/globals.css; there is no
   bundler here, so they are plain custom properties. Keep the two in step:
   if a token changes there, it changes here.

   Hard rules, inherited:
     · no glow           — there are no shadow tokens, and none should appear
     · no gradients      — except the one hairline grid below
     · no bright green   — "nominal" is olive, deliberately understated
     · one accent only   — ember. If two things are ember, one is wrong.
     · radius maxes at 2px
   ════════════════════════════════════════════════════════════════════ */

:root {
  /* surfaces */
  --ink: #0b0d0c;
  --ink-panel: #0d100f;
  --ink-raised: #121615;
  --ink-sunken: #060807;

  /* type */
  --bone: #e8e6df;
  --bone-dim: #9a998f;
  --bone-faint: #63645d;

  /* structure */
  --rule: #1c201e;
  --rule-bright: #2c322f;

  /* the single accent */
  --ember: #d4562b;
  --ember-dim: #7f3319;

  /* signal states — muted on purpose */
  --ok: #7a8b7f;
  --warn: #c8a24a;
  --hold: #6e7e8c;
  --down: #a4483a;

  --mono: "Martian Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --sans: "Archivo", ui-sans-serif, system-ui, -apple-system, sans-serif;

  --radius: 2px;
  --gutter: clamp(1.25rem, 4vw, 3rem);

  color-scheme: dark;
}

* {
  box-sizing: border-box;
  border-color: var(--rule);
}

html {
  -webkit-text-size-adjust: 100%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.5;
  /* Instruments never use proportional figures. */
  font-variant-numeric: tabular-nums;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

::selection {
  background: var(--ember);
  color: var(--ink);
}

:focus-visible {
  outline: 1px solid var(--ember);
  outline-offset: 3px;
}

/* Squared-off hairline scrollbar, to match the chrome. */
::-webkit-scrollbar { width: 10px; height: 10px }
::-webkit-scrollbar-track { background: var(--ink-sunken) }
::-webkit-scrollbar-thumb { background: var(--rule-bright); border: 3px solid var(--ink-sunken) }
::-webkit-scrollbar-thumb:hover { background: var(--ok) }

.mono {
  font-family: var(--mono);
  font-variant-ligatures: none;
  font-variant-numeric: tabular-nums;
}
.muted { color: var(--bone-dim) }

/* The instrument-label voice: tiny, wide, uppercase mono. Everything that
   labels rather than speaks uses it. */
.readout,
.eyebrow,
.ledger th,
.pill,
.slug,
.tier-label {
  font-family: var(--mono);
  font-size: 0.625rem;
  line-height: 1.1;
  letter-spacing: 0.32em;
  text-transform: uppercase;
}

/* ── nav ──────────────────────────────────────────────────────────────
   62px to match the site's masthead exactly, so crossing between the two
   does not shift the page under you. */
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  height: 62px;
  /* Full-bleed bar, but its contents line up with .wrap below rather than
     running to the window edge — otherwise the wordmark sits left of the
     first heading and the whole page looks off its axis. */
  padding: 0 max(var(--gutter), calc((100% - 1080px) / 2));
  border-bottom: 1px solid var(--rule);
  background: rgba(11, 13, 12, 0.85);
  backdrop-filter: blur(12px);
  position: sticky;
  top: 0;
  z-index: 50;
}
.brand {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  text-decoration: none;
  color: var(--bone);
}
/* The ember square from the site wordmark, rotating on hover. */
.brand-mark {
  position: relative;
  display: block;
  width: 10px;
  height: 10px;
  border: 1px solid var(--ember);
  flex: none;
}
.brand-mark::after {
  content: "";
  position: absolute;
  inset: 2px;
  background: var(--ember);
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.brand:hover .brand-mark::after { transform: rotate(45deg) }
.brand-text { display: flex; flex-direction: column; line-height: 1 }
.brand-name { font-size: 15px; font-weight: 600; letter-spacing: 0.24em }
.brand-sub {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--bone-faint);
}

.nav nav { display: flex; align-items: center; gap: 1.75rem; flex-wrap: wrap }
.nav nav a,
.linkbtn {
  position: relative;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--bone-dim);
  padding: 0.5rem 0;
  transition: color 0.3s;
}
.nav nav a:hover,
.linkbtn:hover { color: var(--bone) }
/* Underline grows from the left rather than fading — a measured movement. */
.nav nav a::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 1px;
  width: 0;
  background: var(--ember);
  transition: width 0.3s;
}
.nav nav a:hover::after { width: 100% }
.nav .logout-form { display: inline-flex; margin: 0 }
.linkbtn { background: none; border: 0; cursor: pointer; font-family: var(--mono) }

.wrap {
  flex: 1;
  width: 100%;
  max-width: 1080px;
  margin: 0 auto;
  padding: 3rem var(--gutter) 5rem;
}

/* ── type ─────────────────────────────────────────────────────────── */
h1 {
  font-size: clamp(1.9rem, 4vw, 2.6rem);
  letter-spacing: -0.03em;
  line-height: 1.05;
  font-weight: 600;
  margin: 0.2rem 0 0.7rem;
}
h2 {
  font-size: 1.25rem;
  letter-spacing: -0.02em;
  font-weight: 600;
  margin: 2.75rem 0 0.9rem;
}
h3 { margin: 0.2rem 0 0.4rem; font-size: 1.05rem; font-weight: 600 }
a { color: var(--bone) }
.eyebrow { color: var(--ember); display: block }
.lede { font-size: 1.05rem; color: var(--bone-dim); max-width: 62ch; line-height: 1.6 }
.hint { color: var(--bone-faint); font-size: 0.86rem; line-height: 1.6 }
/* Inline links inside secondary copy. Ember rather than bone, so a call to
   action buried in a hint is still findable at a glance. */
.hint a, .lede a, .desc a { color: var(--ember); text-decoration: none }
.hint a:hover, .lede a:hover, .desc a:hover { text-decoration: underline }
.hero { padding: 0.5rem 0 2.25rem; border-bottom: 1px solid var(--rule) }

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 0.6rem;
  margin-top: 2.5rem;
}
.section-head h1, .section-head h2 { margin: 0 }

/* ── store grid ───────────────────────────────────────────────────── */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: 1rem;
  margin-top: 1.4rem;
}
/* The instrument housing: flat, hairlined, never shadowed. */
.card, .panel {
  position: relative;
  background: var(--ink-panel);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  transition: border-color 0.3s;
}
.card:hover { border-color: var(--rule-bright) }
.card-top { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem }
.card h3 { margin: 0 }
.card h3 a { color: var(--bone); text-decoration: none; transition: color 0.3s }
.card h3 a:hover { color: var(--ember) }
.slug { color: var(--bone-faint) }
.desc { color: var(--bone-dim); font-size: 0.9rem; margin: 0.1rem 0; flex: 1; line-height: 1.6 }
.card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.5rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--rule);
}
.price { font-family: var(--mono); font-size: 1.2rem; letter-spacing: -0.02em }
.per { font-family: var(--mono); font-size: 0.625rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--bone-faint) }

/* ── buttons ──────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  background: var(--ember);
  color: var(--ink);
  border: 1px solid var(--ember);
  border-radius: var(--radius);
  padding: 0.75rem 1.4rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  font-weight: 600;
  /* Narrower than the .readout tracking elsewhere, and never wrapping. At
     0.32em a two-word label breaks mid-phrase inside the button, which reads
     as a layout bug rather than as emphasis. */
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.3s, border-color 0.3s, color 0.3s;
}
.btn:hover { background: var(--bone); border-color: var(--bone); color: var(--ink) }
.btn-sm { padding: 0.45rem 0.85rem; font-size: 0.5625rem; letter-spacing: 0.14em }
.btn-lg { padding: 0.9rem 1.8rem }
.btn-quiet {
  background: transparent;
  color: var(--bone-dim);
  border-color: var(--rule-bright);
}
.btn-quiet:hover { background: transparent; border-color: var(--bone-faint); color: var(--bone) }
.btn[disabled], .btn:disabled { opacity: 0.4; cursor: not-allowed }

/* ── pills ────────────────────────────────────────────────────────── */
.pill {
  display: inline-block;
  padding: 0.28rem 0.55rem;
  border: 1px solid transparent;
  border-radius: var(--radius);
  vertical-align: middle;
}
.pill-ok { color: var(--ok); border-color: rgba(122, 139, 127, 0.4) }
.pill-off { color: var(--bone-faint); border-color: var(--rule-bright) }
.pill-warn { color: var(--warn); border-color: rgba(200, 162, 74, 0.4) }

/* ── detail ───────────────────────────────────────────────────────── */
.back {
  display: inline-block;
  margin-bottom: 1.2rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--bone-faint);
  text-decoration: none;
  transition: color 0.3s;
}
.back:hover { color: var(--ember) }
.detail { max-width: 68ch }
.spec {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 2.5rem;
  margin: 1.6rem 0;
  border-top: 1px solid var(--rule);
  padding-top: 0.2rem;
}
.spec div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  border-bottom: 1px solid var(--rule);
  padding: 0.7rem 0;
}
.spec dt {
  margin: 0;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--bone-faint);
}
.spec dd { margin: 0; font-family: var(--mono); font-size: 0.9rem }
.trunc { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }

/* ── forms ────────────────────────────────────────────────────────── */
.stack { display: flex; flex-direction: column; gap: 1rem; max-width: 380px; margin-top: 1.4rem }
.stack.narrow { max-width: 440px }
label {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  font-family: var(--mono);
  font-size: 0.625rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--bone-faint);
}
input, select {
  font: inherit;
  font-size: 0.95rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--rule-bright);
  border-radius: var(--radius);
  background: var(--ink-sunken);
  color: var(--bone);
  text-transform: none;
  letter-spacing: normal;
}
input:focus, select:focus {
  outline: 1px solid var(--ember);
  outline-offset: 1px;
  border-color: var(--ember);
}
input.mono { font-family: var(--mono) }
input.sm { padding: 0.4rem 0.5rem; width: 7rem }
input[type="file"] { padding: 0.45rem; font-size: 0.8rem }
.auth { max-width: 380px }
.alt { font-size: 0.9rem; color: var(--bone-dim) }
.alt a { color: var(--ember); text-decoration: none }
.alt a:hover { text-decoration: underline }

/* Errors get the one non-ember signal colour, because an error that looks
   like the accent is an error nobody reads as a problem. */
.error, .formerror {
  color: var(--down);
  background: rgba(164, 72, 58, 0.08);
  border: 1px solid rgba(164, 72, 58, 0.35);
  border-left: 2px solid var(--down);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  font-size: 0.9rem;
  margin: 1rem 0;
}

/* Confirmation, not alarm. Olive rather than ember, so a "that worked"
   message never competes with the accent reserved for actions. */
.notice {
  color: var(--ok);
  background: rgba(122, 139, 127, 0.07);
  border: 1px solid rgba(122, 139, 127, 0.3);
  border-left: 2px solid var(--ok);
  border-radius: var(--radius);
  padding: 0.75rem 0.9rem;
  font-size: 0.9rem;
  margin: 1rem 0;
}

/* Recovery codes. Two columns of monospace, sized to be read off a screen
   and typed by hand — this list is what somebody uses on their worst day. */
.codes {
  list-style: none;
  margin: 0.9rem 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 0.5rem 1.5rem;
}
.codes li {
  font-size: 1.05rem;
  letter-spacing: 0.1em;
  padding: 0.35rem 0;
  border-bottom: 1px solid var(--rule);
  user-select: all;
}

/* ── ledger tables ────────────────────────────────────────────────── */
.ledger { width: 100%; border-collapse: collapse; font-size: 0.9rem; margin-top: 0.9rem }
.ledger th {
  text-align: left;
  color: var(--bone-faint);
  font-weight: 400;
  border-bottom: 1px solid var(--rule-bright);
  padding: 0.7rem 0.6rem;
  white-space: nowrap;
}
.ledger td { border-bottom: 1px solid var(--rule); padding: 0.75rem 0.6rem; vertical-align: middle }
.ledger tr:hover td { background: var(--ink-panel) }
.row-action form, .inline { display: inline-flex; gap: 0.4rem; align-items: center; margin: 0 }
.inline input[type="file"] { font-size: 0.75rem; max-width: 160px }

.empty {
  color: var(--bone-dim);
  border: 1px dashed var(--rule-bright);
  border-radius: var(--radius);
  padding: 1.4rem;
  /* Hatch fill — reads as "reserved", not as "broken". */
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(232, 230, 223, 0.017) 0 1px,
    transparent 1px 9px
  );
}
.empty a { color: var(--ember); text-decoration: none }
.empty a:hover { text-decoration: underline }

.device {
  background: var(--ink-panel);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  display: flex;
  gap: 0.9rem;
  align-items: center;
  flex-wrap: wrap;
}
.device .hint { flex-basis: 100%; margin: 0 }

.callout {
  background: var(--ink-panel);
  border: 1px solid var(--rule);
  border-left: 2px solid var(--ember);
  border-radius: var(--radius);
  padding: 1.1rem 1.3rem;
  margin: 1.6rem 0;
}
.callout code {
  font-family: var(--mono);
  background: var(--ink-sunken);
  border: 1px solid var(--rule);
  padding: 0.1rem 0.4rem;
  border-radius: var(--radius);
  font-size: 0.85em;
}
.steps { margin: 0.7rem 0 0; padding-left: 1.3rem; color: var(--bone-dim) }
.steps li { margin: 0.45rem 0 }

.alerts { list-style: none; padding: 0; margin: 0.7rem 0 }
.alerts li {
  display: flex;
  gap: 0.9rem;
  align-items: center;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--rule);
  font-size: 0.88rem;
  color: var(--bone-dim);
}

.totp-enroll {
  margin: 1.4rem 0;
  padding: 1.25rem;
  background: var(--ink-panel);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
}
.totp-enroll .secret {
  font-family: var(--mono);
  font-size: 1.2rem;
  letter-spacing: 0.14em;
  margin: 0.4rem 0 0.7rem;
  word-break: break-all;
  user-select: all;
}
.totp-enroll details { margin-top: 0.5rem; color: var(--bone-dim); font-size: 0.88rem }
.totp-enroll summary { cursor: pointer; color: var(--bone-faint) }

.foot {
  border-top: 1px solid var(--rule);
  padding: 1.4rem var(--gutter);
  color: var(--bone-faint);
  font-size: 0.75rem;
  text-align: center;
}

/* ── licence tiers ────────────────────────────────────────────────── */
.tiers {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0.9rem;
  margin: 1rem 0 1.2rem;
}
.tier {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  align-items: flex-start;
  margin: 0;
  background: var(--ink-panel);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 1.25rem;
}
.tier-label { color: var(--bone-dim) }
.tier-price { font-family: var(--mono); font-size: 1.65rem; letter-spacing: -0.02em; margin-top: 0.4rem }
.tier-per { font-family: var(--mono); font-size: 0.7rem; color: var(--bone-faint) }
.tier button, .tier .btn { margin-top: 0.9rem; width: 100% }

/* ── licence key entry ────────────────────────────────────────────── */
.keyinput {
  font-family: var(--mono);
  font-size: 1.05rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.8rem 0.9rem;
  width: 100%;
  max-width: 26rem;
}
.keyinput::placeholder { color: var(--bone-faint); letter-spacing: 0.08em }

/* ── one-time licence key reveal ──────────────────────────────────────
   The order page, immediately after settlement. Deliberately louder than a
   .hint: this is the only render in which the key exists, so it has to
   survive a skim. Corner brackets mark it as the thing to look at — two
   corners, not four, because symmetry reads as a border. */
.keybox {
  position: relative;
  background: var(--ink-panel);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  padding: 1.25rem 1.4rem;
  margin: 1.4rem 0;
}
.keybox::before,
.keybox::after {
  content: "";
  position: absolute;
  width: 11px;
  height: 11px;
  pointer-events: none;
  border-color: var(--ember);
}
.keybox::before { top: -1px; left: -1px; border-top: 1px solid; border-left: 1px solid }
.keybox::after { bottom: -1px; right: -1px; border-bottom: 1px solid; border-right: 1px solid }
.keybox .readout { display: block; color: var(--ember) }
.keybox .key {
  font-family: var(--mono);
  margin: 0.7rem 0 0.8rem;
  font-size: 1.4rem;
  letter-spacing: 0.08em;
  word-break: break-all;
  user-select: all;
}
.keybox .hint { margin: 0 }

@media (max-width: 640px) {
  .nav { gap: 0.75rem }
  .nav nav { gap: 1rem }
  .brand-sub { display: none }
  .spec { grid-template-columns: 1fr }
  .wrap { padding: 2rem var(--gutter) 3.5rem }
  .ledger { font-size: 0.82rem }
  .ledger th, .ledger td { padding: 0.5rem 0.35rem }
  .keybox .key { font-size: 1.05rem }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}
