/* Warpdrive web surfaces — shared palette, buttons, and appearance dock.
   The splash and the guide pages each used to carry their own copy of the
   token block, which is how they drifted into looking like separate products.
   One file now, linked by every page.

   Palettes are keyed off data-splash-theme on <html>; the light variants have
   to out-specify `body.lightmode`, which sets its tokens on a descendant of
   the element carrying the theme attribute. */

/* ---- Warpdrive — Midnight Gold, the wormhole (mirrors WarpPalette + the house mock sheet) ---- */
:root {
  --canvas:#080D1B; --dim:#0E152A; --panel:#141D38; --panel2:#1B2542;
  --ink:#EDEFF6; --muted:#8791AB; --gold:#E4B75F; --gold-text:#E4B75F;
  --ongold:#0F1526;
  --danger:#F0705A; --ok:#63C989; --info:#6EA8F0; --warn:#E4B75F;
  --inkrgb:237,239,246; --goldrgb:228,183,95;
  --line:rgba(var(--goldrgb),.20); --line2:rgba(var(--goldrgb),.45);
  --bar:rgba(7,12,25,.78); --deep:#050812;
  --card-shadow:0 16px 40px -18px rgba(0,0,0,.55);
  --sans:"Trebuchet MS",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;
}
/* Both selectors: the pre-paint boot script can only class <html>, so the
   first frame is already right, and applyTheme keeps <body> in step for the
   `body.lightmode ...` rules the pages define locally. */
html.lightmode, body.lightmode {
  --canvas:#F8F5EE; --dim:#EFEBE0; --panel:#FFFFFF; --panel2:#F3EEE1;
  --ink:#1B2440; --muted:#5D6478; --gold:#A8791F; --gold-text:#8A6316;
  --ongold:#0F1526;
  --danger:#B73524; --ok:#16A34A; --info:#22579C; --warn:#8A6316;
  --inkrgb:27,36,64; --goldrgb:168,121,31;
  --line:#DCD6C6; --line2:#9C8654;
  --bar:rgba(248,245,238,.82); --deep:#EFEBE0;
  --card-shadow:0 1px 2px rgba(27,36,64,.05),0 12px 30px -14px rgba(27,36,64,.14);
}

/* A skin changes the whole page, lettering included — that is what makes
   switching one read as a reskin rather than a filter. Each face is a stack
   of what the platform already has, so nothing is downloaded. */

/* ---- Space — the FTL deck. Cold, low-chroma, ice-blue instrumentation ----
   Saturation stays down deliberately: a skin you sit in front of all day is
   not the place for a fully saturated accent. */
html[data-splash-theme="space"] {
  --canvas:#060A12; --dim:#0B1220; --panel:#111B2C; --panel2:#18253A;
  --ink:#E6EDF5; --muted:#8496AC; --gold:#8FC4E0; --gold-text:#A6D3EA;
  --ongold:#08121C;
  --danger:#E8836F; --ok:#79C9A6; --info:#8FC4E0; --warn:#D9B87C;
  --inkrgb:230,237,245; --goldrgb:143,196,224;
  --bar:rgba(6,10,18,.80); --deep:#04070D;
  /* Instrument lettering: narrow, technical, a little clipped. */
  --sans:"Avenir Next Condensed","Helvetica Neue",Inter,"Segoe UI",Roboto,sans-serif;
}
html[data-splash-theme="space"].lightmode,
html[data-splash-theme="space"] body.lightmode {
  --canvas:#F1F4F8; --dim:#E4EAF1; --panel:#FFFFFF; --panel2:#E9EFF6;
  --ink:#16202E; --muted:#556478; --gold:#2F6B8C; --gold-text:#275C7A;
  /* The accent is dark here, so a label sitting on it flips to light. */
  --ongold:#FFFFFF;
  --danger:#B73524; --ok:#16794F; --info:#275C7A; --warn:#8A6316;
  --inkrgb:22,32,46; --goldrgb:47,107,140;
  --line:#D3DCE6; --line2:#89A2B6;
  --bar:rgba(241,244,248,.86); --deep:#E4EAF1;
  --card-shadow:0 1px 2px rgba(22,32,46,.05),0 12px 30px -14px rgba(22,32,46,.16);
}

/* ---- Office — the day job. Warm paper and graphite, muted teal accent ---- */
html[data-splash-theme="office"] {
  --canvas:#16151A; --dim:#1E1D22; --panel:#26252B; --panel2:#302E36;
  --ink:#ECEAE4; --muted:#9C978D; --gold:#78B3A6; --gold-text:#8CC2B5;
  --ongold:#121816;
  --danger:#E8836F; --ok:#8CC2B5; --info:#8FB4D0; --warn:#D9B87C;
  --inkrgb:236,234,228; --goldrgb:120,179,166;
  --bar:rgba(22,21,26,.82); --deep:#100F13;
  /* The face of a printed memo. */
  --sans:Georgia,"Iowan Old Style","Times New Roman",serif;
}
html[data-splash-theme="office"].lightmode,
html[data-splash-theme="office"] body.lightmode {
  --canvas:#F6F3ED; --dim:#EBE6DC; --panel:#FFFFFF; --panel2:#F0ECE3;
  --ink:#26251F; --muted:#6B675E; --gold:#3D7A6E; --gold-text:#336A5F;
  --ongold:#FFFFFF;
  --danger:#B73524; --ok:#336A5F; --info:#2C5F86; --warn:#8A6316;
  --inkrgb:38,37,31; --goldrgb:61,122,110;
  --line:#DED8CB; --line2:#9C9384;
  --bar:rgba(246,243,237,.86); --deep:#EBE6DC;
  --card-shadow:0 1px 2px rgba(38,37,31,.05),0 12px 30px -14px rgba(38,37,31,.16);
}

/* ================= brand mark (Folded Space) =================
   Lives here so the header, the footer, and the guide pages all animate the
   one mark instead of each carrying a hand-simplified copy. */
/* ---- Animated brand mark (Folded Space) — shared keyframes ---- */
@keyframes wmMouthSpin { to { stroke-dashoffset: -72; } }
@keyframes wmMouthPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }
@keyframes wmMidSpin { to { stroke-dashoffset: -65; } }
@keyframes wmLineFlow { to { stroke-dashoffset: -18; } }
@keyframes wmThroatFlow { to { stroke-dashoffset: -52; } }
@keyframes wmPlaneDrift { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-1.6px); } }
@keyframes wmPlaneDriftDown { 0%,100% { transform: translateY(0); } 50% { transform: translateY(1.6px); } }
@keyframes wmDepthBreath { 0%,100% { transform: scale(1); opacity: 1; } 50% { transform: scale(.9); opacity: .7; } }
@keyframes wmTransit {
  0% { transform: translateY(0); opacity: 0; }
  12% { opacity: 1; }
  88% { opacity: 1; }
  100% { transform: translateY(37px); opacity: 0; }
}
.wm-plane-top { transform-origin: 60px 19px; animation: wmPlaneDrift 5.2s ease-in-out infinite; }
.wm-plane-bottom { transform-origin: 60px 52px; animation: wmPlaneDriftDown 5.2s ease-in-out infinite; }
.wm-mouth { stroke-dasharray: 18 6; }
.wm-mouth-top { transform-origin: 78px 21px; animation: wmMouthSpin 5s linear infinite, wmMouthPulse 3.4s ease-in-out infinite; }
.wm-mouth-bottom { transform-origin: 78px 49px; animation: wmMouthSpin 6.4s linear infinite reverse, wmMouthPulse 3.4s ease-in-out 1.7s infinite; }
.wm-ring-mid { stroke-dasharray: 8 5; animation: wmMidSpin 4.2s linear infinite reverse; }
.wm-ring-mid-b { animation-direction: normal; }
.wm-depth { transform-origin: 78px 21px; animation: wmDepthBreath 3.2s ease-in-out infinite; }
.wm-depth-b { transform-origin: 78px 49px; animation-delay: 1.6s; }
.wm-gridline { stroke-dasharray: 5 4; animation: wmLineFlow 1.6s linear infinite; }
.wm-g2 { animation-delay: .25s; }
.wm-g3 { animation-delay: .5s; }
.wm-throat { stroke-dasharray: 6 5; animation: wmThroatFlow 2.4s linear infinite; }
.wm-particle { animation: wmTransit 2.4s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  .wm-plane-top, .wm-plane-bottom, .wm-mouth-top, .wm-mouth-bottom,
  .wm-ring-mid, .wm-depth, .wm-gridline, .wm-throat, .wm-particle {
    animation: none;
  }
}

/* ============================ buttons ============================
   The adopted A+F shared control system, per docs/warpdrive-visual-contract-v1.md
   and the controls sheet in docs/ui-mocks/warpdrive-flutter-mocks.html: squared
   3px, ghost by default, primary carries a gold tint and gold text rather than
   a filled gold block, disabled is dotted. No uppercase marketing buttons — the
   splash runs the same controls as the app. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 11px 18px;
  border-radius: 3px;
  /* A transparent border, not none: the disabled state swaps in a dotted one,
     and without the reserved 1px every dead button stands taller than its live
     neighbours and breaks a shared button row. */
  border: 1px solid transparent;
  font-family: var(--sans); font-size: 13.5px; font-weight: 650;
  letter-spacing: .01em;
  color: var(--ink); background: transparent;
  text-decoration: none; cursor: pointer;
  transition: background .12s ease, color .12s ease;
  -webkit-tap-highlight-color: transparent;
}
/* House interaction rule, applied everywhere:
     inactive  plain, no box of its own
     hover     the text changes colour and nothing else moves
     active    a background tint, which is the only thing that gets one
   No hover outlines, no hover backgrounds, no borders appearing under the
   pointer. Focus rings stay — they are an accessibility affordance, not
   decoration. */
.btn:hover { color: var(--gold); text-decoration: none; }
.btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* Primary carries the tint at rest: it is the emphasised action, so its
   background is state, not hover feedback. */
.btn-gold { background: rgba(var(--goldrgb),.22); color: var(--gold); }
.btn-ghost { background: transparent; color: var(--ink); }
.btn[disabled] {
  cursor: default; background: transparent; color: var(--muted);
  border: 1px dotted rgba(var(--inkrgb),.4);
}
.btn-small { padding: 8px 13px; font-size: 12.5px; }
.btn svg { flex: 0 0 auto; }

/* ====================== floating appearance dock ======================
   The web twin of the Flutter app's _MinimalThemeDock, parked in the
   bottom-right corner so the theme is one click away from anywhere. */
.dock {
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  display: flex; align-items: center; gap: 4px;
  /* No container: the icon and the dropdown sit on the page as themselves. */
}
/* Not every page carries a global border-box reset, and these are sized
   against the viewport — measure padding and border inside the width. */
.dock, .dock * { box-sizing: border-box; }
.dock-pop { position: relative; }
.dock-btn {
  display: inline-flex; align-items: center; gap: 7px;
  height: 32px; padding: 0 10px;
  border: 1px solid transparent; border-radius: 6px;
  background: none; color: var(--ink);
  font: inherit; font-size: 12.5px; font-weight: 800;
  letter-spacing: 0; text-transform: none;
  cursor: pointer;
}
.dock-btn:hover { color: var(--gold); }
.dock-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.dock-btn svg { flex: none; }
.dock-icon { width: 32px; padding: 0; justify-content: center; }
/* One button, two glyphs: the visible one reports the mode you are in,
   matching _ThemeModeToggleButton. */
.dock-moon, body.lightmode .dock-sun { display: block; }
.dock-sun, body.lightmode .dock-moon { display: none; }
.dock-theme { min-width: 104px; justify-content: space-between; }
.dock-menu {
  position: absolute; right: 0; bottom: calc(100% + 10px); z-index: 40;
  min-width: 154px; padding: 6px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); box-shadow: var(--card-shadow);
}
.dock-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 8px; border: 0; border-radius: 6px;
  background: none; color: var(--ink); font: inherit;
  text-align: left; cursor: pointer;
}
.dock-item:hover { color: var(--gold); }
.dock-item[aria-checked="true"] { background: rgba(var(--goldrgb),.16); color: var(--gold); }
.dock-item b { font-size: 12.5px; font-weight: 800; }
/* The tick keeps its width when inactive, so the labels stay in a column
   instead of shifting as the selection moves. */
.dock-check { width: 12px; flex: none; color: var(--gold-text); font-size: 12px; visibility: hidden; }
.dock-item[aria-checked="true"] .dock-check { visibility: visible; }

/* ============================ site header ============================
   The same bar on the splash and on every guide page: brand, section links,
   sign-in. Moving between pages must not feel like moving between products,
   so only what is under the header changes. */
.nav {
  position: sticky; top: 0; z-index: 40;
  background: var(--bar);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.nav-inner {
  max-width: 1120px; margin: 0 auto; padding: 0 22px;
  display: flex; align-items: center; gap: 26px;
  height: 62px;
}
.nav-wide .nav-inner { max-width: 1240px; padding: 0 24px; }
.brand {
  display: inline-flex; align-items: center; gap: 11px;
  color: var(--ink); text-decoration: none;
  font-size: 18px; font-weight: 900; letter-spacing: -.2px;
  white-space: nowrap;
}
.brand:hover { text-decoration: none; }
.brand svg { display: block; }
/* Which page you are on, shown the way a breadcrumb would. */
.brand-sep { color: var(--muted); font-weight: 400; }
.brand-doc { color: var(--muted); font-weight: 700; font-size: 13px; white-space: nowrap; }
.nav-links { display: flex; gap: 8px; margin-right: auto; }
.nav-links a {
  color: var(--muted); text-decoration: none;
  font-size: 13px; font-weight: 700; letter-spacing: .02em;
  white-space: nowrap;
}
/* Hover lifts the text and nothing else. The section you are actually in is
   the one thing that gets a background — that is what "active" looks like
   everywhere in this product. */
.nav-links a { border-radius: 3px; padding: 6px 9px; }
.nav-links a:hover { color: var(--ink); text-decoration: none; }
.nav-links a.active { color: var(--gold); background: rgba(var(--goldrgb),.16); }
.nav-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.nav-actions .btn { white-space: nowrap; }
@media (max-width: 720px) {
  .nav-links { display: none; }
  .brand-sep, .brand-doc { display: none; }
}

/* ============================ page footer ============================
   Wordmark and links on the left, credits on the right. */
.footer {
  background: var(--dim);
  border-top: 1px solid var(--line);
  /* The bottom padding clears the floating dock: at the end of the page it
     reaches 64px up from the viewport floor, pinned right — exactly where the
     credit line sits. */
  padding: 34px 0 84px;
}
.footer-inner {
  display: flex; flex-wrap: wrap; gap: 18px 28px;
  align-items: center; justify-content: space-between;
  color: var(--muted); font-size: 12.5px;
}
.footer-brand {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--ink); text-decoration: none;
  font-size: 15px; font-weight: 900; letter-spacing: -.2px;
}
/* No colour override: the mark strokes in currentColor and keeps its own gold
   inner rings, so the footer renders the identical header mark. */
.footer-brand svg { display: block; }
.footer-links { display: flex; flex-wrap: wrap; gap: 8px 20px; margin-right: auto; }
.footer-links a {
  color: var(--muted); text-decoration: none;
  font-size: 12.5px; font-weight: 700;
}
.footer-links a:hover { color: var(--ink); }
.footer-credits {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 12px;
  justify-content: flex-end;
}
.footer-tag { letter-spacing: .18em; text-transform: uppercase; font-size: 10px; font-weight: 900; }
/* Separator, not punctuation: it goes when the pair wraps onto two lines. */
.footer-sep { opacity: .5; }
@media (max-width: 700px) {
  .footer-inner { justify-content: flex-start; }
  .footer-links { margin-right: 0; }
  .footer-credits { justify-content: flex-start; }
}
@media (max-width: 460px) {
  .footer-sep { display: none; }
}
