/* ==========================================================================
   The shell: everything a signed-in page has before it has content.

   No raw hex below the token block, no typed radii, and a visible focus ring
   on every control including the ones that only appear on hover - a control
   reachable only under a mouse is a control half the people cannot press.
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--parchment);
  color: var(--cocoa);
  font-family: var(--body);
  font-size: var(--t-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

h1, h2, h3 {
  font-family: var(--display);
  color: var(--charcoal);
  margin: 0;
  letter-spacing: -.01em;
}

p { margin: 0; }

b, strong { font-weight: 700; }

:focus-visible {
  outline: 2px solid var(--terracotta);
  outline-offset: 2px;
}

/* A keyboard user should not have to walk every card to reach the board. */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  background: var(--charcoal);
  color: var(--cream);
  padding: 10px 16px;
  border-radius: var(--r-pill);
  font-family: var(--display);
  font-size: var(--t-button);
  letter-spacing: .16em;
  text-transform: uppercase;
  text-decoration: none;
}
.skip:focus { left: 12px; top: 12px; }

/* ── masthead ─────────────────────────────────────────────────────────── */
/*
   Matched to the live WordPress board's own masthead - measured off it
   directly on 23 August 2026, not approximated: a dark bar rather than a
   light one, a striped "serape" rule as the page's top edge, and a single-line
   brand lockup rather than a stacked eyebrow-and-heading. The token names
   differ from the live site's raw hex because everything here already goes
   through tokens.css; the pixels match.
*/

/* ── the sidebar's share of the shell ────────────────────────────────────
   Layout only - the rail's own colors and rows are sidebar.css's. This is
   what the reference build calls .has-sidebar: padding on the body rather
   than a margin on every child, because margin-left on each child would
   overwrite what that child asked for. A page that centres itself asks with
   margin: 0 auto, and a margin here would win that fight and leave the page
   flush against the rail with its dead space all on one side - which is
   exactly what happened the first time this was tried with margins instead.
*/
:root { --serape-h: 7px; --sb-off: 236px; }

body.has-sidebar {
  padding-left: var(--sb-off);
  transition: padding-left .16s ease;
}

/* The serape stays full-bleed above the rail rather than sharing its inset -
   it is an edge for the whole viewport, the same way the reference build's
   dev banner spans the window above a sidebar that starts below it. A
   negative margin equal to the padding a static block just inherited makes
   it grow back out to the full width, rather than needing one. */
body.has-sidebar > .serape { margin-left: calc(-1 * var(--sb-off)); }

.serape {
  height: var(--serape-h);
  flex: none;
  background: repeating-linear-gradient(90deg,
    var(--terracotta) 0 26px, var(--masa) 26px 52px,
    var(--done) 52px 78px, var(--clay) 78px 104px, var(--cocoa) 104px 130px);
}

.masthead {
  background: var(--charcoal);
  flex: none;
}

.masthead-in {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px 22px 0;
}

.brand {
  font-family: var(--display);
  font-weight: 700;
  font-size: 23px;
  letter-spacing: -.01em;
  color: var(--cream);
  margin-right: auto;
}

.brand em {
  font-style: italic;
  font-weight: 600;
  color: var(--masa-on-dark);
}

.brand span {
  font-family: var(--display);
  font-size: var(--t-badge);
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--masa-soft-on-dark);
  margin-left: 13px;
  vertical-align: middle;
}

.tallies {
  display: flex;
  gap: 22px;
  margin: 0;
}

.tally dt {
  font-family: var(--display);
  font-size: var(--t-badge);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--masa-soft-on-dark);
}

.tally dd {
  font-family: var(--display);
  font-size: 24px;
  font-weight: 700;
  color: var(--cream);
  margin: 0;
  font-variant-numeric: tabular-nums;
}

/* --attention itself is 2.5:1 on charcoal, well under AA - its own pale tint
   reads at 12.83:1 instead, and still lands unmistakably in the alert family
   rather than borrowing an unrelated hue just because it happens to pass. */
.tally.is-hot dd { color: var(--attention-tint); }

.btn {
  display: inline-block;
  font-family: var(--display);
  font-size: var(--t-button);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  padding: 7px 14px;
  border: 1px solid var(--masa-border-45);
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--cream);
  text-decoration: none;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s;
}
.btn:hover { background: var(--masa-hover-16); border-color: var(--masa-on-dark); }
.btn.is-on { background: var(--masa); border-color: var(--masa); color: var(--charcoal); }

/* Loud on purpose. The one thing worse than a board full of invented clients
   is a board full of invented clients nobody noticed. */
.sample-banner {
  background: var(--attention-tint);
  border-top: 1px solid var(--attention);
  color: var(--attention-ink);
  padding: 9px 22px;
  font-size: 13px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition: none !important;
    animation: none !important;
    scroll-behavior: auto !important;
  }
}


/* ── the board is open ──────────────────────────────────────────────────
   Shown only while no account exists - see app/core/guard.py, which is the
   one state the door stands down in. Loud on purpose: this is not an empty
   state, it is the single configuration nobody should leave a reachable
   board sitting in, and it removes itself the moment that stops being
   true. */

.open-board {
  margin: 0;
  padding: 10px 24px;
  background: var(--attention-tint);
  color: var(--attention-ink);
  border-bottom: 1px solid var(--attention);
  font-size: 13.5px;
  line-height: 1.55;
}
.open-board strong { font-weight: 600; }
.open-board code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12.5px;
  padding: 1px 5px;
  border-radius: var(--r-card);
  background: var(--white);
  border: 1px solid var(--attention);
}

/* IT DOES NOT GET THE SERAPE'S FULL-BLEED TREATMENT, and that was the first
   attempt. The stripe above pulls itself left under the rail because it is
   decoration and has nothing to lose there; this has words in it, and the
   negative margin slid the first of them underneath the sidebar - the
   banner read "pen this board" on screen. Text stays in the column that has
   room for it. */
