/* Stirling portal — design tokens and the components the front door needs.
 *
 * WHY THIS IS ITS OWN FILE AND NOT static_wall_app/styles/tokens.css
 *
 * Stirling is separating from Levant onto its own cluster, its own database and its
 * own release cadence. Sharing a stylesheet across that boundary would mean a Levant
 * change could restyle a live operations console with nobody intending it. The VALUES
 * are copied deliberately — same company, same brand, and tokens.css had already done
 * the work of measuring the status contrast pairings, which is not work worth redoing
 * badly. If the brand moves, both files move.
 *
 * WHAT THIS DELIBERATELY DOES NOT INHERIT
 *
 * The old twin loaded five stylesheets totalling ~7,600 lines, of which styles.css
 * alone is 6,165. `.twin-kpi` had been defined eleven times across three files, and the
 * surface had been re-skinned three times (stirling-modern, stirling-motion,
 * stirling-rebrand) before those were deleted. Starting again is the point; a fourth
 * re-skin is not what was wrong.
 *
 * SINGLE SCHEME, PAINTED EXPLICITLY. Cream and forest, no dark mode — the same choice
 * tokens.css made when the dark re-skin was retired. Every surface sets its own
 * background and colour rather than inheriting, so the page cannot end up showing one
 * scheme's text on another's ground.
 */

:root {
  /* Brand */
  --c-forest:     #1F4D3C;
  --c-forest-d:   #123328;
  --c-moss:       #97BC62;
  --c-sage:       #C8D4CE;
  --c-cream:      #F7F4EC;
  --c-cream-soft: #FBF9F2;
  --c-paper:      #FFFFFF;
  --c-ink:        #1A1A1A;
  --c-ink-soft:   #55605A;
  --c-gold:       #C4993A;

  /* Status. Ink-on-tint pairs, each measured — status is NEVER colour alone in this
   * system, so every chip that uses these also carries a word. */
  --status-ok-ink:     #1B5E43;  --status-ok-bg:    #E8F0DC;  /* ≈6.4:1 */
  --status-watch-ink:  #8A4B16;  --status-watch-bg: #FBEBD2;  /* ≈5.6:1 */
  --status-alert-ink:  #A23320;  --status-alert-bg: #FBECE6;  /* ≈6.1:1 */

  /* Surfaces */
  --page:  #F6F2E9;
  --hair:  rgba(31, 77, 60, .12);
  --shadow-card: 0 1px 2px rgba(18, 51, 40, .06), 0 10px 28px -20px rgba(18, 51, 40, .45);

  /* Scale */
  --r-sm: 10px; --r-md: 14px; --r-lg: 20px; --r-pill: 9999px;
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px; --s-7: 48px;

  --f-head: "Fraunces", ui-serif, Georgia, serif;
  --f-body: "Manrope", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --t-eyebrow: .72rem;
  --t-body:    1rem;
  --t-lead:    1.125rem;
  --t-h2:      1.5rem;
  --t-h1:      2.25rem;

  --motion: 200ms cubic-bezier(.2, .8, .2, 1);
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  /* 16px minimum on mobile: the audience includes people who will not zoom. */
  font: 400 var(--t-body)/1.6 var(--f-body);
  color: var(--c-ink);
  background: var(--page);
  min-height: 100vh;
}

h1, h2, h3 { font-family: var(--f-head); font-weight: 500; margin: 0; text-wrap: balance; line-height: 1.2; }
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
p  { margin: 0; }

/* Keyboard-only focus, 3px, gold. Never removed — the old surface got this right and
 * it is one of the few things carried over unchanged. */
:focus-visible {
  outline: 3px solid var(--c-gold);
  outline-offset: 2px;
  border-radius: 3px;
}

/* The rail on the old cockpit was fifteen items and the first interactive thing on
 * the page. There was no skip link. */
.skip {
  position: absolute; left: var(--s-3); top: -100px;
  background: var(--c-forest); color: var(--c-cream);
  padding: var(--s-3) var(--s-4); border-radius: var(--r-sm);
  text-decoration: none; font-weight: 600; z-index: 50;
  transition: top var(--motion);
}
.skip:focus { top: var(--s-3); }

/* --- layout ------------------------------------------------------------- */

.shell { max-width: 60rem; margin: 0 auto; padding: var(--s-6) var(--s-4) var(--s-7); }
.centred { display: flex; min-height: 100vh; align-items: center; justify-content: center; padding: var(--s-4); }
.stack { display: flex; flex-direction: column; gap: var(--s-4); }
.stack-lg { display: flex; flex-direction: column; gap: var(--s-6); }

.card {
  background: var(--c-paper);
  border: 1px solid var(--hair);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: var(--s-6);
  width: 100%;
  max-width: 30rem;
}

.eyebrow {
  font-size: var(--t-eyebrow); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--c-ink-soft); margin: 0;
}
.lead { font-size: var(--t-lead); color: var(--c-ink-soft); }
.muted { color: var(--c-ink-soft); font-size: .9rem; }

/* --- wordmark ------------------------------------------------------------ */

.wordmark { display: flex; align-items: baseline; gap: var(--s-2); }
.wordmark b { font-family: var(--f-head); font-size: 1.5rem; font-weight: 600; color: var(--c-forest); }
.wordmark span { font-size: .8rem; color: var(--c-ink-soft); letter-spacing: .04em; }

/* --- form ---------------------------------------------------------------- */

label { display: block; font-weight: 600; font-size: .9rem; margin-bottom: var(--s-2); }

input[type="email"] {
  width: 100%;
  font: 400 var(--t-body)/1.4 var(--f-body);
  color: var(--c-ink);
  background: var(--c-cream-soft);
  border: 1px solid var(--hair);
  border-radius: var(--r-sm);
  /* 44px minimum target. */
  padding: 13px var(--s-4);
}
input[type="email"]:focus { background: var(--c-paper); }
input[type="email"][aria-invalid="true"] { border-color: var(--status-alert-ink); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 44px; padding: 12px var(--s-5);
  font: 600 var(--t-body)/1 var(--f-body);
  border: 1px solid transparent; border-radius: var(--r-md);
  cursor: pointer;
  transition: background var(--motion), color var(--motion), border-color var(--motion);
}
.btn-primary { background: var(--c-forest); color: var(--c-cream); }
.btn-primary:hover:not(:disabled) { background: var(--c-forest-d); }
.btn-quiet { background: transparent; color: var(--c-forest); border-color: var(--hair); }
.btn-quiet:hover:not(:disabled) { background: var(--c-cream-soft); }
/* Colour is never the only signal: a disabled button also stops being a pointer and
 * carries aria-disabled or the disabled attribute. */
.btn:disabled { opacity: .55; cursor: not-allowed; }

/* --- feedback: empty and error must not look the same -------------------- */

.note {
  display: flex; gap: var(--s-3); align-items: flex-start;
  padding: var(--s-3) var(--s-4); border-radius: var(--r-sm);
  font-size: .93rem;
}
/* Each state gets a distinct ground, ink AND a word — on the old surface, errors and
 * empties shared one grey italic class and several panels sat on "Loading…" forever,
 * which became the de-facto 403. */
.note-ok    { background: var(--status-ok-bg);    color: var(--status-ok-ink); }
.note-watch { background: var(--status-watch-bg); color: var(--status-watch-ink); }
.note-error { background: var(--status-alert-bg); color: var(--status-alert-ink); }
.note-empty { background: var(--c-cream-soft);    color: var(--c-ink-soft); border: 1px dashed var(--hair); }
.note b { font-weight: 700; }
.note svg { flex: 0 0 auto; margin-top: 2px; }

/* --- chooser ------------------------------------------------------------- */

.choices { display: grid; gap: var(--s-3); grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); list-style: none; margin: 0; padding: 0; }
.choice {
  display: block; text-decoration: none; color: inherit; cursor: pointer;
  background: var(--c-paper); border: 1px solid var(--hair); border-radius: var(--r-md);
  padding: var(--s-5);
  transition: border-color var(--motion), background var(--motion);
}
/* Hover changes colour, never size — a scale transform shifts the neighbours. */
.choice:hover { border-color: var(--c-forest); background: var(--c-cream-soft); }
.choice .name { font-family: var(--f-head); font-size: 1.2rem; color: var(--c-forest); display: block; }
.choice .key  { font-size: .8rem; color: var(--c-ink-soft); }

/* --- header + switcher --------------------------------------------------- */

.topbar {
  background: linear-gradient(155deg, var(--c-forest), var(--c-forest-d));
  color: var(--c-cream);
  padding: var(--s-4) var(--s-5);
}
.topbar .inner { max-width: 60rem; margin: 0 auto; display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; }
.topbar .wordmark b { color: var(--c-cream); }
.topbar .wordmark span { color: var(--c-sage); }
.topbar .spacer { flex: 1 1 auto; }
.switcher { display: flex; align-items: center; gap: var(--s-2); }
.switcher select {
  font: 500 .95rem var(--f-body);
  min-height: 44px; padding: 8px var(--s-3);
  color: var(--c-ink); background: var(--c-paper);
  border: 1px solid transparent; border-radius: var(--r-sm);
  cursor: pointer;
}

.spinner {
  width: 1em; height: 1em; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: spin 700ms linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  /* A spinner that cannot spin must still read as busy, so it becomes a static ring
   * rather than an invisible element. */
  .spinner { border-top-color: currentColor; opacity: .5; }
}

@media (max-width: 640px) {
  .shell { padding: var(--s-4) var(--s-3) var(--s-6); }
  .card { padding: var(--s-5); }
  :root { --t-h1: 1.75rem; }
}
