/* ═══════════════════════════════════════════════════════════════════════
   Turagh Technologies — brand.css
   Design tokens, reset, type, and shared components. Every page links this
   file first. Nothing page-specific belongs here — see site.css (marketing)
   and account.css (auth / intake / profile).

   Token values are the eleven brand colours and are not to be changed
   here. Everything else is derived from them; never introduce a third hue.
   ═══════════════════════════════════════════════════════════════════════ */

:root{
  --bg:#eef3fa;
  --surface:#ffffff;
  --surface-2:#e2ebf7;
  --border:#cbd9ec;
  --text:#06152d;
  --text-dim:#51678d;
  /* Navigation ink. Its own token rather than --text-dim, which is the right
     weight for a caption sitting under something but too pale for the only
     labels on the page a visitor has to read to get anywhere. 7.4:1 here
     against --text-dim's 5.1:1 — both pass AA, and the difference is what makes
     11px uppercase legible rather than merely compliant. */
  --nav-ink:#3b4f73;
  --accent:#094ff0;
  --accent-strong:#094ff0;
  --accent-soft:#dbe8ff;
  --accent-2:#05688c;
  --accent-contrast:#ffffff;

  /* derived — atmosphere */
  --glow-a: color-mix(in srgb, var(--accent) 12%, transparent);
  --glow-b: color-mix(in srgb, var(--accent-2) 10%, transparent);
  --veil:   color-mix(in srgb, var(--surface) 74%, transparent);
  --hair:   color-mix(in srgb, var(--border) 80%, transparent);
  --lift:   color-mix(in srgb, var(--text) 6%, transparent);
  --grain-opacity:.026;
  --shadow: 0 1px 2px rgba(6,21,45,.06), 0 24px 60px -32px rgba(6,21,45,.26);

  --font-display: "IBM Plex Sans Condensed", "Archivo Narrow", "Arial Narrow", sans-serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;

  --wrap: 1220px;
  /* Vertical rhythm between form fields. One number, used by every form
     on the site — the contact form, the auth screens and the brief grid
     each carried their own before, which is why they never matched. */
  --field-gap: 30px;
  /* Opening quotation mark, used by .quote-card. Declared here so the shape
     lives with the other tokens rather than inline in one component. */
  --quote-mark:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 34 26'%3E%3Cpath d='M14.2 0C6.4 3.1 1.6 9.4 1.6 16.6c0 5.6 3.3 9.4 8 9.4 4.2 0 7.3-3.1 7.3-7.2 0-4-2.9-7-6.8-7-.8 0-1.6.1-2.1.3.9-3.9 4-7.4 8.2-9.4L14.2 0Zm17.2 0c-7.8 3.1-12.6 9.4-12.6 16.6 0 5.6 3.3 9.4 8 9.4 4.2 0 7.3-3.1 7.3-7.2 0-4-2.9-7-6.8-7-.8 0-1.6.1-2.1.3.9-3.9 4-7.4 8.2-9.4L31.4 0Z' fill='%23000'/%3E%3C/svg%3E");
  --ease: cubic-bezier(.22,.61,.36,1);
  --ease-out: cubic-bezier(.16,1,.3,1);
}

/* Light is the default, unconditionally — there is deliberately no
   prefers-color-scheme block. The palette above applies to every visitor
   regardless of their system setting, and the page stays light with scripting
   disabled rather than depending on the head script to hold the default.
   Dark is reached only by choosing it. */
:root[data-theme="dark"]{
  --bg:#06152d; --surface:#0b2043; --surface-2:#122a54; --border:#1e3a68;
  --text:#ffffff; --text-dim:#8fa8cc; --nav-ink:#b9cbe6; --accent:#0985f5; --accent-strong:#094ff0;
  --accent-soft:#0d2b57; --accent-2:#05acfe; --accent-contrast:#ffffff;
  --glow-a: color-mix(in srgb, var(--accent) 22%, transparent);
  --glow-b: color-mix(in srgb, var(--accent-2) 15%, transparent);
  --veil:   color-mix(in srgb, var(--surface) 58%, transparent);
  --lift:   color-mix(in srgb, #ffffff 8%, transparent);
  --grain-opacity:.040;
  --shadow: 0 1px 2px rgba(0,0,0,.5), 0 32px 72px -40px rgba(0,0,0,.9);
}

/* ─────────────────────────── Reset ─────────────────────────── */
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
body{
  margin:0; background:var(--bg); color:var(--text);
  font-family:var(--font-body); font-size:16px; line-height:1.65;
  -webkit-font-smoothing:antialiased; overflow-x:hidden;
  transition:background .5s var(--ease), color .5s var(--ease);
}
img,svg,canvas{ display:block; max-width:100%; }
a{ color:inherit; }
h1,h2,h3,h4,p,figure{ margin:0; }
ul{ margin:0; padding:0; list-style:none; }
button{ font:inherit; color:inherit; background:none; border:none; cursor:pointer; }
:focus-visible{ outline:2px solid var(--accent-2); outline-offset:4px; border-radius:2px; }

/* film grain — the single texture that keeps large flat fields from feeling dead */
body::after{
  content:""; position:fixed; inset:0; z-index:9999; pointer-events:none;
  opacity:var(--grain-opacity);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

.wrap{ max-width:var(--wrap); margin:0 auto; padding:0 32px; }
.wrap-narrow{ max-width:840px; margin:0 auto; padding:0 32px; }
@media (max-width:640px){ .wrap,.wrap-narrow{ padding:0 22px; } }

/* ─────────────────────────── Type ─────────────────────────── */
.eyebrow{
  font-family:var(--font-display); font-weight:500; font-size:.7rem;
  letter-spacing:.28em; text-transform:uppercase; color:var(--text-dim);
  display:inline-flex; align-items:center; gap:12px;
}
.eyebrow::before{ content:""; width:24px; height:1px; background:linear-gradient(90deg, transparent, var(--accent)); }
.eyebrow.plain::before{ display:none; }
.eyebrow em{ font-style:normal; color:var(--accent); }

.display{ font-family:var(--font-display); font-weight:200; letter-spacing:-.02em; line-height:1.02; text-wrap:balance; }
h1.page-title,
h2.section-title{
  font-family:var(--font-display); font-weight:300;
  font-size:clamp(2rem, 3.6vw, 3.1rem);
  letter-spacing:-.02em; line-height:1.06; text-wrap:balance;
}
.page-title b, .section-title b{ font-weight:600; color:var(--accent-2); }
.lede{ color:var(--text-dim); font-size:1.06rem; max-width:56ch; text-wrap:pretty; }

/* placeholder marker — visually loud so it can never ship unnoticed.
   Trust content is never invented; this is what "obviously a placeholder"
   looks like. */
.slot{
  color:var(--accent);
  background:color-mix(in srgb, var(--accent) 10%, transparent);
  border:1px dashed color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius:2px; padding:0 6px; font-style:normal;
}

/* ───────────────────────── Buttons ───────────────────────── */
.btn{
  position:relative; display:inline-flex; align-items:center; justify-content:center; gap:10px;
  padding:14px 26px; border-radius:2px;
  font-family:var(--font-display); font-weight:500; font-size:.8rem;
  letter-spacing:.1em; text-transform:uppercase; text-decoration:none;
  border:1px solid transparent; overflow:hidden;
  transition:transform .4s var(--ease-out), border-color .3s var(--ease),
             color .3s var(--ease), background .3s var(--ease);
  white-space:nowrap;
}
.btn-primary{ background:var(--accent-strong); color:var(--accent-contrast); }
.btn-primary::before{
  content:""; position:absolute; inset:0;
  background:linear-gradient(120deg, transparent 30%, rgba(255,255,255,.35) 50%, transparent 70%);
  transform:translateX(-120%); transition:transform .8s var(--ease-out);
}
.btn-primary:hover::before{ transform:translateX(120%); }
.btn-primary:hover{ transform:translateY(-2px); }
.btn-line{ color:var(--text); border-color:var(--border); background:var(--veil); backdrop-filter:blur(8px); }
.btn-line:hover{ border-color:var(--accent-2); color:var(--accent-2); transform:translateY(-2px); }
.btn-block{ width:100%; }
/* Filter/segment size. The default .btn is a page-level call to action; five of
   them in a card heading read as five calls to action rather than a filter. */
.btn-sm{ padding:9px 16px; font-size:.7rem; letter-spacing:.12em; }
/* The selected filter. Without this the current view was indistinguishable from
   the four links that leave it. */
.btn-line.current{
  border-color:var(--accent-2); color:var(--accent-2);
  background:color-mix(in srgb, var(--accent-2) 10%, transparent);
}
.btn-line.current:hover{ transform:none; }
.btn span{ position:relative; z-index:1; display:inline-flex; align-items:center; gap:10px; }
.btn:disabled{ opacity:.55; cursor:not-allowed; transform:none; }

.arrow-link{
  display:inline-flex; align-items:center; gap:10px;
  font-family:var(--font-display); font-weight:500; font-size:.86rem;
  letter-spacing:.04em; text-decoration:none; color:var(--text);
  transition:gap .3s var(--ease-out), color .3s var(--ease);
}
.arrow-link svg{ width:15px; height:15px; }
.arrow-link:hover{ color:var(--accent-2); gap:16px; }

.text-link{ color:var(--accent-2); text-decoration:none; border-bottom:1px solid transparent; transition:border-color .3s var(--ease); }
.text-link:hover{ border-bottom-color:var(--accent-2); }

/* ───────────────────────── Panel ───────────────────────── */
.panel{
  position:relative; background:var(--veil); backdrop-filter:blur(14px);
  border:1px solid var(--hair); border-radius:3px; padding:32px 30px;
}
/* one-pixel inner highlight along the top edge — where the depth comes from */
.panel::before{
  content:""; position:absolute; left:1px; right:1px; top:0; height:1px;
  background:linear-gradient(90deg, transparent, var(--lift) 30%, var(--lift) 70%, transparent);
}
.panel-flush{ padding:0; overflow:hidden; }

/* ── Account menu ─────────────────────────────────────────────────────────
   Replaces the account link and the brief button in the header once someone
   is signed in.
   ───────────────────────────────────────────────────────────────────────── */
.acct-menu{ position:relative; }

.acct-trigger{
  width:40px; height:40px; border-radius:50%; display:grid; place-items:center;
  border:1px solid var(--border); background:var(--veil); color:var(--text);
  cursor:pointer; transition:border-color .3s var(--ease), color .3s var(--ease);
}
.acct-trigger svg{ width:20px; height:20px; }
.acct-trigger:hover,
.acct-trigger[aria-expanded="true"]{ border-color:var(--accent); color:var(--accent); }

.acct-drop{
  position:absolute; top:calc(100% + 12px); right:0; z-index:60;
  min-width:210px; display:grid; padding:8px;
  background:var(--surface); border:1px solid var(--hair); border-radius:3px;
  box-shadow:var(--shadow);
}
/* A class with display: beats the UA stylesheet's [hidden]{display:none}, so
   without this the menu would render permanently open. */
.acct-drop[hidden]{ display:none; }

.acct-drop a, .acct-drop button{
  display:flex; align-items:center; gap:11px; width:100%;
  padding:11px 12px; border-radius:2px; text-align:left;
  font-family:var(--font-display); font-size:.82rem; letter-spacing:.04em;
  color:var(--text); text-decoration:none; cursor:pointer;
  transition:background .25s var(--ease), color .25s var(--ease);
}
.acct-drop a:hover, .acct-drop button:hover,
.acct-drop a:focus-visible, .acct-drop button:focus-visible{
  background:var(--surface-2); color:var(--accent);
}
.acct-drop svg{ width:17px; height:17px; flex:none; color:var(--text-dim); }
.acct-drop a:hover svg, .acct-drop button:hover svg{ color:var(--accent); }

.acct-drop-sep{ height:1px; background:var(--hair); margin:6px 4px; }

/* Below the drawer breakpoint the burger takes over, and a floating panel
   anchored to a hidden trigger has nothing to anchor to. */
@media (max-width:1140px){ .acct-menu{ display:none; } }

/* Sign-out in the drawer is a button (POST), so it has to be dressed as the
   anchors beside it or it reads as a stray control. */
.drawer .drawer-signout{
  font-family:inherit; font-size:inherit; font-weight:inherit; letter-spacing:inherit;
  color:inherit; background:none; border:none; padding:0;
  text-align:left; cursor:pointer;
}

/* ───────────────────────── Header ───────────────────────── */
header.site{
  position:fixed; top:0; left:0; right:0; z-index:60;
  border-bottom:1px solid transparent;
  transition:background .4s var(--ease), border-color .4s var(--ease);
}
header.site.is-stuck,
header.site.solid{
  background:color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter:blur(18px) saturate(1.3);
  border-bottom-color:var(--hair);
}
.nav{ display:flex; align-items:center; justify-content:space-between; gap:24px; height:84px; }
.brand{ display:flex; align-items:center; gap:13px; text-decoration:none; }
.brand .mark{ width:34px; height:34px; flex:none; border-radius:6px; background:#000519; transition:transform .5s var(--ease-out); }
.brand:hover .mark{ transform:rotate(-8deg) scale(1.06); }
.brand .word{ display:flex; flex-direction:column; gap:3px; line-height:1.05; }
.brand .word b{ font-family:var(--font-display); font-weight:600; font-size:1rem; letter-spacing:.1em; }
/* The lockup's second line. Still small and still wide — it is a wordmark, not
   a label to read at speed — but .58rem of --text-dim at .26em was the faintest
   thing in the header by some way. */
.brand .word span{
  font-family:var(--font-display); font-weight:500; font-size:.62rem; letter-spacing:.2em;
  color:var(--nav-ink); text-transform:uppercase;
}

.nav-links{ display:flex; align-items:center; gap:2px; }
/* Uppercase, tracked and condensed is the look, and it stays. What it cannot
   also be is 11.8px at weight 500 in --text-dim: uppercase throws away the
   ascender and descender shapes a reader uses to recognise a word, tracking
   pulls the remaining letters apart so they stop reading as one, and the
   condensed face narrows every glyph. Three choices that each cost a little
   legibility, stacked on the seven labels that have to be read to navigate.

   Contrast was never the problem — the old colour measured 5.1:1 and passes AA.
   Size and weight were. 12.8px at 600 with the tracking eased to .075em keeps
   the same character and is readable at a glance. */
.nav-links a{
  position:relative; font-family:var(--font-display); font-weight:600; font-size:.8rem;
  letter-spacing:.075em; text-transform:uppercase; text-decoration:none;
  color:var(--nav-ink); padding:10px 14px; transition:color .3s var(--ease);
}
.nav-links a::before{
  content:""; position:absolute; left:14px; bottom:4px; width:0; height:1px;
  background:var(--accent); transition:width .35s var(--ease-out);
}
.nav-links a:hover{ color:var(--text); }
.nav-links a:hover::before{ width:calc(100% - 28px); }
.nav-links a.current{ color:var(--text); }
.nav-links a.current::before{ width:calc(100% - 28px); background:var(--accent-2); }

/* Two groups, not three items in a row. The theme toggle is a utility control;
   sign-in and the brief button are one pair of account actions. A single gap
   for all three read as neither, and left "Sign in" absorbed between a circle
   and a solid button. The pair sits close, the toggle stands off. */
.nav-side{ display:flex; align-items:center; gap:10px; }
/* The toggle sits last, past the call to action, so the row reads
   navigation → account → utility instead of interrupting itself. */
.nav-side .toggle{ margin-left:8px; }
/* Shorter than the page-level button: 51px next to a 36px toggle was the tallest
   thing in an 84px bar and pulled the row out of line. */
.nav-side .btn{ padding:11px 24px; }
.toggle{
  width:36px; height:36px; border:1px solid var(--border); border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  color:var(--text-dim); background:var(--veil); backdrop-filter:blur(8px); flex:none;
  transition:border-color .3s var(--ease), color .3s var(--ease), transform .4s var(--ease-out);
}
.toggle:hover{ border-color:var(--accent-2); color:var(--accent-2); transform:rotate(25deg); }
.toggle svg{ width:16px; height:16px; }
.toggle .i-sun{ display:none; }
:root[data-theme="dark"] .toggle .i-moon{ display:none; }
:root[data-theme="dark"] .toggle .i-sun{ display:block; }

.nav-side .btn, .nav-side .signin{ display:none; }
@media (min-width:820px){ .nav-side .btn, .nav-side .signin{ display:inline-flex; } }
@media (max-width:1140px){ .nav-links{ display:none; } }

/* Same bar, same treatment. Left as it was, it read as a disabled version of
   the links beside it. */
/* Padded so it is a target rather than bare text: at 21px tall with nothing
   around it, it sat flush against the button beside it and was the smallest
   thing to hit in the bar. */
.signin{
  font-family:var(--font-display); font-weight:600; font-size:.8rem;
  letter-spacing:.075em; text-transform:uppercase; text-decoration:none;
  color:var(--nav-ink); transition:color .3s var(--ease);
  padding:11px 12px; align-items:center;
}
.signin:hover{ color:var(--accent-2); }

/* mobile drawer */
.burger{ width:36px; height:36px; display:none; align-items:center; justify-content:center; color:var(--text); }
.burger svg{ width:20px; height:20px; }
@media (max-width:1140px){ .burger{ display:flex; } }
.drawer{
  position:fixed; inset:0; z-index:70; background:var(--bg);
  display:grid; align-content:center; justify-items:center; gap:6px;
  opacity:0; pointer-events:none; transition:opacity .35s var(--ease);
}
.drawer.open{ opacity:1; pointer-events:auto; }
.drawer a{
  font-family:var(--font-display); font-weight:300; font-size:1.7rem;
  letter-spacing:-.01em; text-decoration:none; color:var(--text); padding:10px 20px;
}
.drawer a:hover{ color:var(--accent-2); }
.drawer .close{ position:absolute; top:28px; right:28px; width:40px; height:40px; color:var(--text-dim); }
.drawer .close svg{ width:22px; height:22px; }

/* ───────────────────────── Page head (interior pages) ───────────────────────── */
.page-head{
  position:relative; overflow:hidden;
  padding:150px 0 64px;
  border-bottom:1px solid var(--hair);
}
.page-head::before{
  content:""; position:absolute; inset:-40% -10% auto -10%; height:180%; z-index:-1;
  background:
    radial-gradient(40% 46% at 78% 18%, var(--glow-a), transparent 62%),
    radial-gradient(46% 52% at 18% 70%, var(--glow-b), transparent 64%);
}
.page-head .inner{ display:grid; gap:20px; max-width:760px; }
.crumbs{
  font-family:var(--font-display); font-size:.7rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--text-dim);
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
}
.crumbs a{ text-decoration:none; transition:color .3s var(--ease); }
.crumbs a:hover{ color:var(--accent-2); }
.crumbs i{ font-style:normal; color:var(--accent); }

/* ───────────────────────── Footer ───────────────────────── */
footer.site{ border-top:1px solid var(--hair); padding:56px 0 44px; }
.foot-grid{
  display:grid; grid-template-columns:1.6fr 1fr 1fr 1fr; gap:40px;
  padding-bottom:40px; border-bottom:1px solid var(--hair);
}
@media (max-width:860px){ .foot-grid{ grid-template-columns:1fr 1fr; gap:32px; } }
@media (max-width:520px){ .foot-grid{ grid-template-columns:1fr; } }
.foot-col h4{
  font-family:var(--font-display); font-weight:500; font-size:.68rem;
  letter-spacing:.18em; text-transform:uppercase; color:var(--text-dim); margin-bottom:16px;
}
.foot-col a, .foot-col p{
  display:block; font-size:.9rem; color:var(--text-dim);
  text-decoration:none; padding:5px 0; transition:color .3s var(--ease);
}
.foot-col a:hover{ color:var(--accent-2); }
.foot-about p{ max-width:34ch; padding-top:0; }
.foot{ display:flex; align-items:center; justify-content:space-between; gap:24px; flex-wrap:wrap; padding-top:32px; }
.foot-brand{ display:flex; align-items:center; gap:12px; }
.foot-brand .mark{ width:22px; height:22px; border-radius:4px; background:#000519; }
.foot-brand b{ font-family:var(--font-display); font-weight:500; font-size:.86rem; letter-spacing:.05em; }
.foot-tag{ font-family:var(--font-display); font-size:.72rem; letter-spacing:.14em; color:var(--accent-2); }
.foot-legal{ font-family:var(--font-display); font-size:.72rem; color:var(--text-dim); }

/* Footer addresses. <address> defaults to italic, which reads as a quotation
   rather than a location, and its default block layout leaves no gap between
   lines that are separate places. */
.foot-address{
  font-style:normal; display:grid; gap:6px; margin-top:16px;
  font-size:.86rem; line-height:1.5; color:var(--text-dim);
}

/* ───────────────────────── Form primitives ───────────────────────── */
/* ── Form fields ──────────────────────────────────────────────────────────
   Static labels above real bordered inputs.

   This replaced a floating-label underline pattern, for three reasons rather
   than taste. An empty field said nothing about itself, because the label was
   doubling as the placeholder — you had to focus a field to learn what it
   wanted. A bare underline inside an already-pale panel gave almost no signal
   that the thing was editable at all. And the raised label had to squeeze into
   a reserved row, which put a 0.72-scale uppercase word hard against whatever
   sat above it; a <select> showed it permanently, since its label could never
   be in the resting state.

   The markup did not change. Every field is written control-then-label, so the
   label is pulled above with order:-1 rather than by rewriting twenty fields
   across nine views.
   ───────────────────────────────────────────────────────────────────────── */
.field{ display:flex; flex-direction:column; gap:9px; }

.field label{
  order:-1;                       /* first on screen, second in the DOM */
  font-family:var(--font-display); font-weight:500; font-size:.72rem;
  letter-spacing:.13em; text-transform:uppercase; color:var(--text-dim);
}

.field input, .field select, .field textarea{
  width:100%; font:inherit; font-size:.95rem; color:var(--text);
  /* Recessed against the panel it sits in, so the input reads as somewhere to
     type rather than as another band of the card. */
  background:var(--bg);
  border:1px solid var(--border); border-radius:2px;
  padding:12px 14px;
  transition:border-color .25s var(--ease), background .25s var(--ease),
             box-shadow .25s var(--ease);
}

.field textarea{ min-height:132px; resize:vertical; }

/* appearance:none removes the native arrow, so one is drawn back. A fixed
   slate tone rather than currentColor, which a data URI cannot read. */
.field select{
  appearance:none; -webkit-appearance:none; cursor:pointer;
  padding-right:40px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%236b7a99' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-size:12px 8px;
}

.field input:focus, .field select:focus, .field textarea:focus{
  outline:none;
  border-color:var(--accent);
  background:var(--surface);
  /* A ring rather than a thicker border, so nothing reflows on focus. */
  box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent);
}
.field input:focus + label,
.field select:focus + label,
.field textarea:focus + label{ color:var(--accent); }

.field input::placeholder, .field textarea::placeholder{ color:var(--text-dim); opacity:.7; }

.field .hint{ font-size:.79rem; color:var(--text-dim); }
/* Read-only values shown in a normal field. Recessed and dimmed so it is
   clearly not an input to type in, but still aligned with the fields beside
   it rather than dropping out of the grid as plain text. */
.field input[readonly]:not([data-email-field]){
  background:var(--surface-2); color:var(--text-dim); cursor:default;
}
.field input[readonly]:not([data-email-field]):focus{
  border-color:var(--border); box-shadow:none;
}
/* ── Inline badge ─────────────────────────────────────────────────────────
   A badge sitting beside running text rather than standing alone in its own
   row. The base .badge is sized to hold a line on its own; at the end of a
   field label or a device name it reads as a second heading and takes the eye
   before the name it is annotating does.

   Deliberately NOT scoped to one component. It was `.field label .label-badge`
   at first, which meant the modifier silently did nothing in the session list
   and the full-size badge rendered there instead.
   ───────────────────────────────────────────────────────────────────────── */
.badge-inline{
  padding:2px 8px; font-size:.56rem; letter-spacing:.1em;
  gap:5px; vertical-align:middle; position:relative; top:-1px;
}
/* The dot scales with it, or a 5px dot beside 0.56rem text reads as a bullet. */
.badge-inline::before{ width:4px; height:4px; }

.field.invalid input, .field.invalid select, .field.invalid textarea{
  border-color:var(--accent);
  background:color-mix(in srgb, var(--accent) 5%, var(--bg));
}
/* Errors sit under the field they belong to and are only shown when the server
   marked that field invalid. */
/* The look is unscoped on purpose: a validation message also appears outside a
   .field — the consent checkboxes carry one — and there it still has to read as
   an error rather than as body text. Only hide-until-invalid belongs to fields,
   which are the ones that reserve the row whether or not it is filled. */
.err{ font-size:.79rem; color:var(--accent); display:block; }
.field .err{ display:none; }
.field.invalid .err{ display:block; }
.hint{ display:block; font-size:.79rem; color:var(--text-dim); }

.req{ color:var(--accent); }

/* ── Locked field ─────────────────────────────────────────────────────────
   A value shown in a real input rather than as static text, so it reads as
   part of the form, with the control that would change it sitting inside the
   field where a user looks for it.
   ───────────────────────────────────────────────────────────────────────── */
.field-locked .locked-row{ position:relative; display:block; }
.field-locked input{ padding-right:46px; }

/* Disabled, not merely readonly: readonly still submits, and this value must
   not be changeable through the form that renders it. */
.field-locked input:disabled{
  background:var(--surface-2); color:var(--text-dim);
  cursor:default; opacity:1;   /* Safari fades disabled inputs to unreadable */
}

.field-edit{
  position:absolute; right:8px; top:50%; transform:translateY(-50%);
  width:30px; height:30px; display:grid; place-items:center;
  border-radius:2px; background:none; color:var(--text-dim); cursor:pointer;
  transition:color .25s var(--ease), background .25s var(--ease);
}
.field-edit svg{ width:16px; height:16px; }
.field-edit:hover:not(:disabled){ color:var(--accent); background:var(--surface); }
/* Present but unavailable — the flow behind it is not built. Shown rather than
   hidden so the field says where the change would happen. */
.field-edit:disabled{ opacity:.4; cursor:not-allowed; }

/* A value shown but not editable. Sits beside real fields in the same grid, so
   its label matches .field label exactly — a 0.02rem difference between two
   labels on one row reads as a mistake rather than a distinction. */
.field-static{ display:grid; gap:9px; align-content:start; }
.field-static > span:first-child{
  font-family:var(--font-display); font-weight:500; font-size:.72rem;
  letter-spacing:.13em; text-transform:uppercase; color:var(--text-dim);
}
/* Padded to sit on the same baseline as the bordered input next to it, without
   pretending to be one. */
.field-static > span:nth-child(2){ font-size:.95rem; padding:12px 0; }

.check-line{ display:grid; grid-template-columns:20px 1fr; gap:13px; align-items:start; font-size:.9rem; color:var(--text-dim); }
.check-line input[type="checkbox"]{
  appearance:none; -webkit-appearance:none;
  width:18px; height:18px; margin:3px 0 0; flex:none;
  border:1px solid var(--border); border-radius:2px; background:transparent;
  cursor:pointer; position:relative; transition:border-color .25s var(--ease), background .25s var(--ease);
}
.check-line input[type="checkbox"]:checked{ background:var(--accent-2); border-color:var(--accent-2); }
.check-line input[type="checkbox"]:checked::after{
  content:""; position:absolute; left:5px; top:1px; width:5px; height:10px;
  border:solid var(--accent-contrast); border-width:0 2px 2px 0; transform:rotate(45deg);
}
.check-line a{ color:var(--accent-2); text-decoration:none; }
.check-line a:hover{ text-decoration:underline; }

.form-note{ margin-top:14px; font-size:.82rem; color:var(--text-dim); }
.status{
  font-family:var(--font-display); font-size:.82rem; letter-spacing:.04em;
  display:none; margin-top:16px; padding:12px 14px; border-radius:2px;
}
.status.ok{ display:block; color:var(--accent-2); border:1px solid color-mix(in srgb, var(--accent-2) 45%, transparent); background:color-mix(in srgb, var(--accent-2) 8%, transparent); }
.status.bad{ display:block; color:var(--accent); border:1px solid color-mix(in srgb, var(--accent) 45%, transparent); background:color-mix(in srgb, var(--accent) 8%, transparent); }
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* ── Form tail ────────────────────────────────────────────────────────────
   Consent, bot check, submit, and the note under it, grouped so their spacing
   is one decision instead of an inline margin on each element.

   Two things this fixes. The form used to layer a grid `gap` with per-item
   `margin-top` values of 20/22/26px, so no single rule described the rhythm and
   changing one meant hunting the others. And the Turnstile placeholder is an
   empty <div> until a remote script fills it — as a grid item it consumed a row
   and a margin whether or not that ever happened, which meant the distance
   between the last field and the submit button depended on whether a
   third-party request succeeded. :empty collapses it until it has real content.
   ───────────────────────────────────────────────────────────────────────── */
.form-actions{ display:grid; gap:20px; margin-top:10px; }
/* Grid items stretch by default, which turns every submit into a full-width
   bar. Only .btn-block asks for that. */
.form-grid > .btn:not(.btn-block),
.form-actions > .btn:not(.btn-block){ justify-self:start; }
.form-actions .cf-turnstile:empty{ display:none; }
.form-actions .form-note{ margin-top:0; }

/* prototype banner — every page carries one so nobody mistakes these
   static mockups for the real application */
.proto{
  font-family:var(--font-display); font-size:.68rem; letter-spacing:.14em;
  text-transform:uppercase; text-align:center; padding:7px 20px;
  color:var(--accent); background:color-mix(in srgb, var(--accent) 10%, transparent);
  border-bottom:1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  position:relative; z-index:80;
}

/* ───────────────────────── Reveal ───────────────────────── */
.rv{ opacity:0; transform:translateY(22px); transition:opacity .9s var(--ease-out), transform .9s var(--ease-out); }
.rv.in{ opacity:1; transform:none; }
.rv[data-d="1"]{ transition-delay:.08s; }
.rv[data-d="2"]{ transition-delay:.16s; }
.rv[data-d="3"]{ transition-delay:.24s; }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *{ animation-duration:.001ms !important; animation-iteration-count:1 !important; transition-duration:.001ms !important; }
  .rv{ opacity:1; transform:none; }
}

/* ═══════════════════ View utilities ═══════════════════
   The policy sends `style-src 'self'`, which means the browser discards every
   style="" attribute before layout. Anything a view needs to say about its own
   spacing or display has to be a class or it silently does nothing — so the
   adjustments the views used to carry inline live here instead. */

/* Spacing steps. Only the values actually used appear; a full scale would be
   mostly dead rules. */
.mt-10{ margin-top:10px; }
.mt-14{ margin-top:14px; }
.mt-20{ margin-top:20px; }
.mt-22{ margin-top:22px; }
.mt-30{ margin-top:30px; }
.mt-44{ margin-top:44px; }
.mb-16{ margin-bottom:16px; }
.mb-18{ margin-bottom:18px; }
.mb-26{ margin-bottom:26px; }

/* Line breaks a person typed are content, not formatting — a brief that was
   written as paragraphs has to reach staff as paragraphs. */
.prewrap{ white-space:pre-wrap; }
.breakall{ word-break:break-all; }

/* A one-button form sharing a row with other controls. */
.inline-form{ display:inline; }
.center{ text-align:center; }
.text-sm{ font-size:.88rem; }
.lede-wide{ max-width:none; }

/* Uppercase micro-heading inside a panel — the rung below .card-head h2, used
   where a block needs naming but not a rule under it. */
.sub-label{
  font-family:var(--font-display); font-weight:500; font-size:.7rem;
  letter-spacing:.18em; text-transform:uppercase; color:var(--text-dim);
  margin-bottom:14px;
}

/* A machine-generated identifier quoted in running text — a reference number,
   a correlation id. Tracked and set in the display face so it reads as
   something to copy rather than as prose. */
.ref-id{ font-family:var(--font-display); letter-spacing:.1em; color:var(--accent-2); }

/* Fine print centred under a form's submit button. */
.auth-note{ font-size:.8rem; color:var(--text-dim); text-align:center; margin-top:-10px; }

/* ── Bot check ────────────────────────────────────────────────────────────
   The Turnstile container, invisible on nearly every visit — Cloudflare only
   draws into it when this visitor has to prove something.

   :empty is what keeps that invisibility honest. The div is a child of a grid
   form, so even at zero height it still takes a row and the gap that comes with
   it, and the button sat one field-gap lower than it did before the check
   existed. Hiding it while it holds nothing means a form the widget never
   touches is laid out exactly as if the widget were not there.

   It stops being :empty the moment Cloudflare inserts its iframe, so a visitor
   who IS challenged gets the widget at full size with no rule to undo.
   ───────────────────────────────────────────────────────────────────────── */
.cf-turnstile:empty{ display:none; }

/* A filter or link row that wraps rather than overflowing. */
.chip-row{ display:flex; gap:8px; flex-wrap:wrap; }
.link-row{ display:flex; gap:16px; }

/* Form whose direct children are fields — one gap value governs the whole
   column, so a form's rhythm is set in one place rather than per field. */
.form-grid{ display:grid; gap:var(--field-gap); }

.panel-tight{ padding:22px 20px; }
.panel-narrow{ max-width:560px; }
/* A panel raising something the reader has to act on, marked on the edge
   rather than by tinting the whole surface. */
.panel-alert{ border-left:2px solid var(--accent); }

.ta-tall{ min-height:130px; }
.ta-note{ min-height:90px; }
.mt-18{ margin-top:18px; }
.mt-34{ margin-top:34px; }
.mb-14{ margin-bottom:14px; }
.mb-22{ margin-bottom:22px; }
.push-right{ margin-left:auto; }
.lede-lg{ font-size:1.12rem; }
/* Explanatory sentence inside a panel — quieter than body text, not as small
   as fine print. */
.note{ font-size:.95rem; color:var(--text-dim); }
/* Section heading at panel scale rather than page scale, for a heading that
   introduces a column instead of a whole section. */
.section-title-sm{ font-size:clamp(1.6rem,2.6vw,2.1rem); }
/* The alert panel's own type, so the view carries no styling of its own. */
.panel-alert b{ font-family:var(--font-display); }
.panel-alert p{ color:var(--text-dim); font-size:.92rem; margin-top:6px; }
/* A row's trailing cell when there is nothing to act on — same slot as the
   edit control, but plainly not a control. */
.edit-static{ color:var(--text-dim); }

/* Two halves of one answer. Tighter than the gap between unrelated fields, so
   a password and its confirmation read as one thing to fill in. */
.field-pair{ display:grid; gap:12px; }
/* The field's own 9px gap already separates the meter from its input; the
   meter's stock top margin was stacking on top of that. */
.field .pw-meter{ margin-top:0; }

/* ── Reveal password ──────────────────────────────────────────────────────
   The toggle sits inside the input's box rather than beside it, so the field
   keeps its width and the label above still lines up with every other field. */
.pw-wrap{ position:relative; display:block; }
.pw-wrap input{ padding-right:46px; }
.pw-reveal{
  position:absolute; right:1px; top:1px; bottom:1px; width:44px;
  display:flex; align-items:center; justify-content:center;
  color:var(--text-dim); border-radius:0 2px 2px 0;
  transition:color .25s var(--ease);
}
.pw-reveal:hover{ color:var(--accent-2); }
.pw-reveal svg{ width:18px; height:18px; }
/* One button, two icons — the state lives on the class so the markup does not
   have to be rewritten on every toggle. */
.pw-reveal .i-hide{ display:none; }
.pw-reveal.on .i-show{ display:none; }
.pw-reveal.on .i-hide{ display:block; }

/* Links in the slim footer bar, where there are no columns to inherit from. */
.foot-legal a{ color:var(--text-dim); text-decoration:none; }
.foot-legal a:hover{ color:var(--accent-2); }

/* Registration number. Tabular figures so the digits do not wobble, and it
   never wraps mid-number. */
.reg-no{ font-variant-numeric:tabular-nums; white-space:nowrap; }

/* Social profiles in the footer. A row of outline marks that take the footer's
   own ink, so they sit with the address rather than competing with it. */
.foot-social{ display:flex; gap:10px; margin-top:18px; }
.foot-social a{
  display:flex; align-items:center; justify-content:center;
  width:34px; height:34px; border-radius:50%;
  border:1px solid var(--border); color:var(--text-dim);
  transition:border-color .3s var(--ease), color .3s var(--ease), transform .4s var(--ease-out);
}
.foot-social a:hover{ border-color:var(--accent-2); color:var(--accent-2); transform:translateY(-2px); }
.foot-social svg{ width:17px; height:17px; }
