/* The web app page (Red, 2026-09-05; wired 2026-09-06; touch-up 2026-09-06).
   Lives at drivegiro.com/account/ (the subdomain is deferred, Red).
   Everything is a separate page; nothing sits on top of the home page. Base styles (topbar, drawer, chrome, buttons, .ev rows)
   come from /style.css; this file is the app layout only. */

body.app { background: #0a0806; min-height: 100vh; }
body.app .grain { display: none; }
.app-main { padding-top: 32px; min-height: 100vh; }
.app-main[data-state="out"] .acct-in { display: none; }
.app-main[data-state="in"]  .acct-out { display: none; }
/* the messenger belongs to the signed-in page: no FAB, no popup for a visitor
   who has not signed in (plan 87b lane W — a signed-out tap would open a
   screen that can only wait) */
.app-main[data-state="out"] .msgr-fab, .app-main[data-state="out"] .msgr { display: none; }

/* signed out: centred card */
.app-auth {
  width: min(92vw, 420px); margin: 14vh auto 0;
  border: 1px solid rgba(242,237,230,.1); padding: 34px 30px 26px; background: #0a0806;
}
.app-auth h1.chrome-text { font-size: clamp(2rem, 7vw, 2.8rem); font-weight: 800; font-stretch: condensed; letter-spacing: .08em; text-transform: uppercase; margin: 0 0 10px; line-height: 1; }

/* signed in: side nav + view */
.app-shell { display: grid; grid-template-columns: 1fr; min-height: calc(100vh - 32px); }  /* one column since 2026-09-22 — the rail is gone, the hamburger is the one menu */
.app-side {
  border-right: 1px solid rgba(242,237,230,.08);
  padding: 28px 22px; display: flex; flex-direction: column; gap: 26px;
  position: sticky; top: 32px; height: calc(100vh - 32px);
}
.app-user { display: flex; align-items: center; gap: 12px; }
.app-nav { display: flex; flex-direction: column; gap: 6px; }
.app-nav-link {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; color: rgba(242,237,230,.6); text-decoration: none;
  font-size: .74rem; letter-spacing: .22em; text-transform: uppercase;
  border-left: 2px solid transparent;
}
.app-nav-link:hover { color: #f2ede6; }
.app-nav-link.is-active { color: #f2ede6; border-left-color: #f2ede6; }
.badge { margin-left: auto; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: #f2ede6; color: #0a0806; font-size: .62rem; font-weight: 800; display: inline-grid; place-items: center; letter-spacing: 0; }
.app-home { margin-top: auto; color: rgba(242,237,230,.45); text-decoration: none; font-size: .7rem; letter-spacing: .2em; text-transform: uppercase; }
.app-home:hover { color: #f2ede6; }

.app-view { display: none; padding: 34px clamp(18px, 4vw, 48px) 80px; }
.app-view.is-active { display: block; }
.app-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 18px; flex-wrap: wrap; margin-bottom: 22px; }
.app-head h1.chrome-text { font-size: clamp(2.2rem, 6vw, 3.4rem); font-weight: 800; font-stretch: condensed; letter-spacing: .08em; text-transform: uppercase; margin: 0; line-height: 1; }
.app-filters { display: flex; gap: 8px; flex-wrap: wrap; }
.chip { background: none; border: 1px solid rgba(242,237,230,.18); color: rgba(242,237,230,.65); padding: 8px 12px; cursor: pointer; font: inherit; font-size: .64rem; letter-spacing: .2em; text-transform: uppercase; }
.chip.is-active, .chip:hover { color: #0a0806; background: #f2ede6; border-color: #f2ede6; }

/* event cards */
.ev-grid { list-style: none; margin: 0 0 18px; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 16px; }
.ev-card { background: #100d0b; border: 1px solid rgba(242,237,230,.08); overflow: hidden; }
.ev-card-media { aspect-ratio: 16 / 9; background: #14110f center / cover no-repeat; filter: saturate(.3) brightness(.7); }
.ev-card-body { display: flex; align-items: center; gap: 14px; padding: 14px; }
.ev-actions { display: flex; gap: 6px; align-items: center; }
.ev-save { background: none; border: 1px solid rgba(242,237,230,.25); color: rgba(242,237,230,.7); width: 34px; height: 30px; cursor: pointer; font-size: 14px; }
.ev-save.is-saved { color: #f2ede6; border-color: rgba(242,237,230,.6); }   /* gold -> cream, the site spec (Red, 2026-09-07) */
.acct-form { max-width: 420px; }

/* messenger popup */
.msgr {
  position: fixed; right: 20px; bottom: 20px; z-index: 300;
  width: min(92vw, 360px); height: min(70vh, 520px);
  background: #0a0806; border: 1px solid rgba(242,237,230,.12);
  box-shadow: 0 30px 80px rgba(0,0,0,.6);
  display: flex; flex-direction: column;
  animation: panel-in 260ms cubic-bezier(.2,.7,.2,1);
}
.msgr[hidden] { display: none; }
.msgr-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid rgba(242,237,230,.08); }
.msgr-head .panel-close { position: static; }
.msgr-title { font-size: .72rem; letter-spacing: .24em; text-transform: uppercase; color: rgba(242,237,230,.7); }
.msgr-body { flex: 1; overflow: auto; }
.msgr-list { list-style: none; margin: 0; padding: 0; }
.msgr-thread { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-bottom: 1px solid rgba(242,237,230,.06); cursor: pointer; }
.msgr-thread:hover { background: #100d0b; }
.msgr-thread .acct-avatar { width: 36px; height: 36px; }
.msgr-thread > div { flex: 1; min-width: 0; }
.msgr-name { font-weight: 800; font-stretch: condensed; letter-spacing: .04em; }
.msgr-preview { font-size: .78rem; color: rgba(242,237,230,.5); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.msgr-thread.is-unread .msgr-preview { color: #f2ede6; }
.msgr-time { font-size: .66rem; letter-spacing: .1em; color: rgba(242,237,230,.4); }
.msgr-convo { display: flex; flex-direction: column; height: 100%; }
.msgr-messages { flex: 1; padding: 14px; }
.msgr-compose { display: flex; gap: 8px; padding: 10px; border-top: 1px solid rgba(242,237,230,.08); }
.msgr-compose input { flex: 1; background: #14110f; border: 1px solid rgba(242,237,230,.14); color: #f2ede6; padding: 10px 12px; font: inherit; }
.msgr-compose .btn-primary { padding: 10px 14px; }
.msgr-fab {
  position: fixed; right: 20px; bottom: 20px; z-index: 290;
  width: 52px; height: 52px; border-radius: 50%; border: 0; cursor: pointer;
  background: #f2ede6; color: #0a0806; font-size: 20px; display: grid; place-items: center;
}
.msgr-fab .badge { position: absolute; top: -4px; right: -4px; }
html.msgr-open .msgr-fab { display: none; }

/* ---- WIRING SHELL (plan 80, the app instance, 2026-09-06) -------------------
   Structure only, deliberately plain: the touch-up pass is the site instance's
   and every rule below is meant to be restyled or replaced. Nothing designed
   was renamed. What is new:
   · .auth-step        — the sign-in card's steps (word / signup / code /
     handle / forgot / reset). Only one is ever visible.
   · .panel-error      — the design doc's named slot for loading + error copy;
     [data-kind="ok"] is the same slot saying something went right.
   · .app-soon         — the one honest line under a deferred surface.
   · .acct-confirm     — the typed DELETE step under Settings.
   · .gate-build-item  — one row in the Builds list (the .gate-* classes it
     wraps already live in /style.css, from the home page's door).
   · [data-state="soon"] — chips, nav links and save-stars that are honest
     about not being wired yet. */

.auth-step[hidden] { display: none; }
.auth-step h1.chrome-text { font-size: clamp(2rem, 7vw, 2.8rem); font-weight: 800; font-stretch: condensed; letter-spacing: .08em; text-transform: uppercase; margin: 0 0 10px; line-height: 1; }

.panel-error { margin: 12px 0 0; font-size: .74rem; line-height: 1.5; letter-spacing: .04em; color: #d97a6a; }
.panel-error[data-kind="ok"] { color: rgba(242,237,230,.7); }
.panel-error[hidden] { display: none; }

.app-soon { color: rgba(242,237,230,.55); }
.msgr-body .app-soon { padding: 18px 16px; margin: 0; text-transform: none; letter-spacing: .06em; font-size: .8rem; }

.chip[data-state="soon"], .ev-save[data-state="soon"] { opacity: .35; cursor: default; }
.chip[data-state="soon"]:hover { background: none; color: rgba(242,237,230,.65); border-color: rgba(242,237,230,.18); }
.app-nav-link[data-state="soon"], .drawer-link[data-state="soon"] { opacity: .5; }

.acct-confirm { margin-top: 16px; max-width: 420px; border: 1px solid rgba(217,122,106,.35); padding: 16px; }
.acct-confirm .panel-fine { margin: 0 0 10px; text-transform: none; letter-spacing: .04em; font-size: .76rem; line-height: 1.5; }

.gate-build-item { padding: 10px 0; border-bottom: 1px solid rgba(242,237,230,.06); }
[data-hook="builds-latest"] .btn-primary { width: auto; }

@media (max-width: 760px) {
  .app-shell { grid-template-columns: 1fr; }
  .app-side { position: static; height: auto; border-right: 0; border-bottom: 1px solid rgba(242,237,230,.08); padding: 18px; gap: 14px; }
  .app-nav { flex-direction: row; overflow-x: auto; }
  .app-nav-link { border-left: 0; border-bottom: 2px solid transparent; white-space: nowrap; }
  .app-nav-link.is-active { border-bottom-color: #f2ede6; }
  .app-home { display: none; }
}


/* ---- TOUCH-UP (the site instance, 2026-09-06) ---------------------------
   Restyles the wiring shell above. Hooks and structure untouched. */

/* the sign-in card: steps fade in, one at a time */
.app-auth { animation: panel-in 320ms cubic-bezier(.2,.7,.2,1); }
.auth-step:not([hidden]) { animation: panel-in 260ms cubic-bezier(.2,.7,.2,1); }
.app-auth .panel-fine a { color: rgba(242,237,230,.75); text-decoration: none; border-bottom: 1px solid rgba(242,237,230,.25); }
.app-auth .panel-fine a:hover { color: #fff; border-bottom-color: #fff; }
.code-input {
  text-align: center; font-size: 1.6rem !important; letter-spacing: .5em !important;
  font-weight: 800; font-stretch: condensed; padding: 12px 0 12px .5em !important;
}
.code-input::placeholder { letter-spacing: .5em; color: rgba(242,237,230,.18); }
.panel-form button.btn-primary { margin-top: 4px; }
.panel-form button[disabled] { opacity: .55; cursor: progress; }

/* status + error lines: one grammar */
.panel-error, [data-hook$="-status"] { transition: opacity 200ms; }
.panel-error { padding-left: 12px; border-left: 2px solid #d97a6a; }
.panel-error[data-kind="ok"] { border-left-color: rgba(242,237,230,.35); }
[data-hook$="-status"]:not(:empty) {
  display: inline-block; margin-top: 12px; padding-left: 12px;
  border-left: 2px solid rgba(242,237,230,.25);
  text-transform: none; letter-spacing: .06em; font-size: .76rem; color: rgba(242,237,230,.55);
  animation: status-pulse 1.4s ease-in-out infinite;
}
@keyframes status-pulse { 0%, 100% { opacity: .55; } 50% { opacity: 1; } }

/* loading skeleton: while the feed is empty and the status line is talking,
   the grid area shows three ghost cards with a slow shimmer */
.ev-grid:empty { min-height: 0; }
html.is-loading .ev-grid:empty {
  min-height: 270px;
  background:
    linear-gradient(90deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.035) 50%, rgba(255,255,255,0) 100%) 0 0 / 200% 100% no-repeat,
    repeating-linear-gradient(90deg, #100d0b 0 300px, transparent 300px 316px) 0 0 / 100% 100%;
  animation: skeleton-shimmer 1.8s linear infinite;
  border-radius: 2px;
}
@keyframes skeleton-shimmer { from { background-position: 200% 0, 0 0; } to { background-position: -200% 0, 0 0; } }

/* empty states: give them a room, not a footnote */
.app-empty:not([hidden]) {
  display: block; margin: 8px 0 0; padding: 40px 20px;
  border: 1px dashed rgba(242,237,230,.12); text-align: center;
  text-transform: none; letter-spacing: .06em; font-size: .92rem; color: rgba(242,237,230,.6);
}
.app-soon:not([hidden]) {
  display: block; margin: 8px 0 0; padding: 26px 20px;
  border: 1px solid rgba(242,237,230,.08); background: #0e0b09; text-align: center;
  text-transform: none; letter-spacing: .06em; font-size: .88rem; line-height: 1.6; color: rgba(242,237,230,.6);
}
.app-soon:not([hidden])::before { content: "Soon"; display: block; margin-bottom: 6px; font-size: .6rem; letter-spacing: .3em; text-transform: uppercase; color: rgba(249,107,12,.8); }
.msgr-body .app-soon:not([hidden]) { border: 0; background: none; padding: 26px 18px; }

/* soon-states on controls: dimmed, labelled, no fake affordance */
.chip[data-state="soon"] { opacity: .45; border-style: dashed; }
.chip[data-state="soon"]::after { content: " · soon"; font-size: .55rem; letter-spacing: .2em; color: rgba(249,107,12,.9); }
.app-nav-link[data-state="soon"], .drawer-link[data-state="soon"] { opacity: .45; }
.app-nav-link[data-state="soon"]::after { content: "soon"; margin-left: auto; font-size: .55rem; letter-spacing: .25em; color: rgba(249,107,12,.9); }
.ev-save[data-state="soon"] { display: none; }

/* the planned rows sit above the grid as a short list */
[data-hook="events-planned"]:not([hidden]) { margin-bottom: 26px; }
[data-hook="events-planned"] .ev { background: #14100d; border-color: rgba(242,237,230,.12); }
[data-hook="events-more"]:not([hidden]) { display: block; margin: 6px auto 18px; }

/* event cards: actions drop under the title on narrow cards, and the
   server's refusal sentence sits under the row instead of squeezing it */
.ev-card-body { flex-wrap: wrap; }
.ev-card-body .ev-body { flex: 1 1 160px; }
.ev-card .panel-error, .ev .panel-error { flex-basis: 100%; margin: 6px 0 0; }
.ev-rsvp { transition: background 160ms, color 160ms, border-color 160ms; }
.ev-rsvp:hover { border-color: #f2ede6; }

/* builds */
[data-hook="builds-latest"] { margin: 6px 0 22px; }
[data-hook="builds-latest"] .btn-primary { width: 100%; max-width: 420px; display: block; padding: 16px 20px; font-size: .9rem; }
.gate-build-item { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; padding: 12px 0; max-width: 560px; }
.gate-build-item .panel-fine { margin: 0; }

/* settings: the photo field */
.avatar-field { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin: 4px 0; }
.acct-avatar-lg { width: 72px; height: 72px; }
.avatar-pick { position: relative; overflow: hidden; display: inline-block; padding: 10px 14px; border: 1px solid rgba(242,237,230,.18); color: rgba(242,237,230,.8); cursor: pointer; font-size: .66rem; letter-spacing: .22em; text-transform: uppercase; }
.avatar-pick:hover { color: #fff; border-color: rgba(242,237,230,.5); }
.avatar-pick input { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.avatar-hint { flex-basis: 100%; margin: 0; text-transform: none; letter-spacing: .04em; }
.acct-confirm { animation: panel-in 220ms cubic-bezier(.2,.7,.2,1); }
.acct-danger { border-top: 1px solid rgba(242,237,230,.08); padding-top: 18px; max-width: 420px; }

/* mobile pass */
@media (max-width: 760px) {
  .app-auth { margin-top: 8vh; padding: 28px 22px 22px; }
  .app-view { padding: 22px 16px 90px; }
  .app-head { margin-bottom: 16px; }
  .app-head h1.chrome-text { font-size: 2.2rem; }
  .app-filters { width: 100%; overflow-x: auto; flex-wrap: nowrap; padding-bottom: 4px; -webkit-overflow-scrolling: touch; }
  .chip { white-space: nowrap; }
  .ev-grid { grid-template-columns: 1fr; }
  .app-user { width: 100%; }
  .app-nav { width: 100%; padding-bottom: 2px; scrollbar-width: none; }
  .app-nav::-webkit-scrollbar { display: none; }
  .app-nav-link[data-state="soon"]::after { margin-left: 6px; }
  .msgr { right: 0; bottom: 0; width: 100vw; height: 78vh; }
  .msgr-fab { right: 16px; bottom: 16px; }
  .acct-danger { flex-direction: column; }
  .acct-danger .btn-ghost { width: 100%; }
}

/* builds gate (app instance's 4c16809: account AND the word, both) */
.builds-gate-note { margin: 0 0 12px; text-transform: none; letter-spacing: .04em; font-size: .78rem; color: rgba(242,237,230,.55); }
.builds-unlock { max-width: 420px; flex-direction: row; gap: 8px; margin-bottom: 8px; }
.builds-unlock input[type=password] { flex: 1; min-width: 0; }
.builds-unlock .btn-primary { margin-top: 0; white-space: nowrap; }
[data-hook="builds-list"]:not([hidden]) { animation: panel-in 260ms cubic-bezier(.2,.7,.2,1); }
@media (max-width: 520px) { .builds-unlock { flex-direction: column; } }

/* cooldowns + code tempo (Red, 2026-09-08 — plan 86 §7.3) ---------------------
   A greyed field and its reason. `.field-note` is `.panel-fine` with the top
   margin taken out (it sits inside the label's own 6px gap) and, like
   `.avatar-hint` above it, sentence-cased: these are sentences with a date in
   them, not the uppercase micro-labels the rest of `.panel-fine` carries. No
   new colours — the same cream at the same opacity. */
.panel-form input:disabled { opacity: .45; cursor: not-allowed; }
.field-note {
  margin: 2px 0 0; font-size: .68rem; line-height: 1.5;
  letter-spacing: .04em; text-transform: none;
  color: rgba(242,237,230,.45);
}
/* the code steps: the 5-minute line sits close under the form, and the resend
   link goes quiet (and unclickable) while it counts the 90 seconds down */
.code-life { margin-top: 10px; }
.panel-fine a[aria-disabled="true"] { opacity: .45; pointer-events: none; cursor: default; }

/* the password rule, drawn live (plan 87 §0.7 U13 — lane W, 2026-09-10) ------
   Four dots under a new-password field that fill in as the person types; the
   mismatch line under the confirm field; the copy-law sentence under both.
   `.field-note`'s grammar (sentence case, the same cream at .45), no new
   colours: a met check is the cream at .85, an unmet one the note's own
   opacity. The dot is a glyph, not an icon, so it needs no asset. */
.pw-checks {
  list-style: none; margin: 2px 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 4px 14px;
  font-size: .68rem; line-height: 1.5; letter-spacing: .04em;
  color: rgba(242,237,230,.45);
}
.pw-checks li::before { content: "○ "; }
.pw-checks li[data-ok="1"] { color: rgba(242,237,230,.85); }
.pw-checks li[data-ok="1"]::before { content: "● "; }
.pw-mismatch { color: #d97a6a; }
.pw-mismatch[hidden] { display: none; }
.pw-why { margin-top: 4px; }
.panel-form button[disabled]:not([data-busy="1"]) { cursor: not-allowed; }

/* the messenger, wired (plan 87b lane W step 1, 2026-09-10) ---------------------
   STRUCTURE ONLY, in the popup's own grammar: the road's screens reuse
   .panel-form / .panel-fine / .panel-error / .code-input; the thread pane gains
   a head, a "load earlier" button and message rows. No new colours — the
   card's #14110f and the cream. The brand instance restyles; every class
   below is listed in the plan doc as a markup delta. */
.msgr-state { padding: 22px 18px; }
.msgr-state[hidden] { display: none; }
/* `.msgr-convo` is display:flex above, which beat the `hidden` attribute (the
   design shell's latent bug — the pane's head showed under the list) */
.msgr-convo[hidden], .msgr-list[hidden] { display: none; }
.msgr-state-title { margin: 0 0 8px; font-weight: 800; font-stretch: condensed; letter-spacing: .06em; text-transform: uppercase; font-size: .95rem; }
.msgr-state-line { margin: 0 0 12px; text-transform: none; letter-spacing: .04em; font-size: .8rem; line-height: 1.55; color: rgba(242,237,230,.65); }
.msgr-state .panel-form { margin-bottom: 8px; }
.msgr-state .panel-form input { width: 100%; }
.msgr-state-links { margin-top: 10px; text-transform: none; letter-spacing: .04em; font-size: .76rem; line-height: 1.8; }
.msgr-state-links a { color: rgba(242,237,230,.75); text-decoration: none; border-bottom: 1px solid rgba(242,237,230,.25); }
.msgr-state-links a:hover { color: #fff; border-bottom-color: #fff; }
.msgr-state-links a[aria-disabled="true"] { opacity: .45; pointer-events: none; }
.msgr-section { padding: 10px 14px 4px; font-size: .62rem; letter-spacing: .3em; text-transform: uppercase; color: rgba(249,107,12,.8); }
.msgr-empty { padding: 26px 18px; margin: 0; text-transform: none; letter-spacing: .06em; font-size: .8rem; text-align: center; color: rgba(242,237,230,.55); }
.msgr-convo-head { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid rgba(242,237,230,.08); }
.msgr-back { background: none; border: 0; color: rgba(242,237,230,.7); font-size: 18px; cursor: pointer; padding: 0 4px; }
.msgr-back:hover { color: #fff; }
.msgr-earlier { margin: 8px auto 0; display: block; font-size: .6rem; padding: 6px 10px; }
.msgr-earlier[hidden] { display: none; }
.msgr-messages { overflow-y: auto; display: flex; flex-direction: column; gap: 8px; }
.msgr-msg { max-width: 82%; align-self: flex-start; background: #14110f; border: 1px solid rgba(242,237,230,.08); padding: 8px 10px; }
.msgr-msg.is-mine { align-self: flex-end; background: #f2ede6; color: #0a0806; border-color: #f2ede6; }
.msgr-msg.is-unavailable .msgr-msg-text { font-style: italic; opacity: .6; }
.msgr-msg-who { font-size: .62rem; letter-spacing: .18em; text-transform: uppercase; color: rgba(242,237,230,.5); margin-bottom: 3px; }
.msgr-msg-quote { font-size: .72rem; opacity: .6; border-left: 2px solid currentColor; padding-left: 8px; margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.msgr-msg-label { font-size: .6rem; letter-spacing: .2em; text-transform: uppercase; opacity: .55; margin-bottom: 3px; }
.msgr-msg-text { font-size: .86rem; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.msgr-msg-meta { margin-top: 4px; font-size: .6rem; letter-spacing: .08em; opacity: .5; }
.msgr-convo .panel-error { margin: 4px 14px 0; }
.signout-note { text-transform: none; letter-spacing: .04em; font-size: .68rem; line-height: 1.5; opacity: .6; margin-top: 8px; }

/* ---- THE EVENTS VIEW IS A MAP VIEW (plan 92 §3.4, lane W, 2026-09-21) ------
   Red's Google-Maps picture (R9): the rail (240px, above) · this list column
   (360px) · the map filling the rest. The view stops scrolling as a page — the
   LIST scrolls inside its column and the map holds still, which is what makes
   it read as a map app instead of a feed with a picture on it.
   Colours: the cream, the two card blacks, and for a LIVE event the APP's accent
   (#F96B0C, src/theme/colors.ts) — Red, 2026-09-22: "match the app"; gold stays the
   Mutuals meaning and is not used here.
   Narrow (≤760px, the breakpoint the rest of this file keeps): one column, and
   the "Map" chip trades the list for the map. */

.ev-view.is-active {
  display: grid; grid-template-columns: 360px 1fr;
  padding: 0; height: calc(100vh - 32px); min-height: 520px;
}
.ev-pane { display: flex; flex-direction: column; min-width: 0; min-height: 0; border-right: 1px solid rgba(242,237,230,.08); }
.ev-head { padding: 28px 22px 0; margin-bottom: 14px; }
.ev-head h1.chrome-text { font-size: 2.4rem; }
.ev-chips { padding: 0 22px 14px; display: flex; flex-direction: column; gap: 8px; border-bottom: 1px solid rgba(242,237,230,.08); }
.ev-chips .app-filters { gap: 6px; }
.ev-chips .chip { padding: 7px 10px; font-size: .58rem; }

/* "Pick dates" — two native date fields, the web's own picker (§3.4) */
.ev-dates { display: flex; gap: 12px; padding-top: 2px; }
.ev-dates[hidden] { display: none; }
.ev-date-field {
  display: flex; flex-direction: column; gap: 4px; flex: 1;
  font-size: .58rem; letter-spacing: .24em; text-transform: uppercase; color: rgba(242,237,230,.5);
}
.ev-date-field input {
  background: #14110f; border: 1px solid rgba(242,237,230,.14); color: #f2ede6;
  font: inherit; font-size: .78rem; padding: 7px 8px; color-scheme: dark;
}

.ev-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 10px 22px 40px; }
.ev-scroll[hidden] { display: none; }
.ev-scroll .ev-list { margin: 0; gap: 0; }
.ev-section { margin: 20px 0 6px; font-size: .58rem; letter-spacing: .3em; text-transform: uppercase; color: rgba(242,237,230,.45); }

/* a list row: cover, date, title + one meta line, RSVP. The whole row is the
   way into the details panel; only the RSVP button acts on its own. */
.ev-row {
  display: flex; align-items: center; gap: 12px; cursor: pointer;
  padding: 12px 10px; margin: 0 -10px;
  border-bottom: 1px solid rgba(242,237,230,.06);
  transition: background 140ms;
}
.ev-row:hover, .ev-row.is-selected { background: #14110f; }
.ev-row.is-selected { box-shadow: inset 2px 0 0 #f2ede6; }
.ev-row-media { width: 54px; height: 40px; flex: none; background: #14110f center / cover no-repeat; filter: saturate(.3) brightness(.75); }
.ev-row .ev-when { min-width: 32px; }
.ev-row .ev-title { font-size: .92rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ev-row .ev-meta { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ev-row.is-live .ev-meta { color: rgba(249,107,12,.95); }
.ev-row .ev-rsvp { padding: 7px 10px; font-size: .58rem; }

/* the selected event, in the list's place */
.ev-details { flex: 1; min-height: 0; overflow-y: auto; padding: 16px 22px 40px; }
.ev-details[hidden] { display: none; }
.ev-back {
  background: none; border: 0; padding: 0 0 14px; cursor: pointer; font: inherit;
  font-size: .62rem; letter-spacing: .24em; text-transform: uppercase; color: rgba(242,237,230,.6);
}
.ev-back:hover { color: #f2ede6; }
.ev-details-media { aspect-ratio: 16 / 9; background: #14110f center / cover no-repeat; filter: saturate(.3) brightness(.75); }
.ev-details-head { margin: 16px 0 12px; }
.ev-details-title { margin: 0; font-size: 1.5rem; font-weight: 800; font-stretch: condensed; letter-spacing: .04em; line-height: 1.15; }
.ev-details-club { margin-top: 4px; font-size: .7rem; letter-spacing: .14em; color: rgba(242,237,230,.5); }
.ev-details-facts { display: flex; flex-direction: column; gap: 6px; padding: 14px 0; border-top: 1px solid rgba(242,237,230,.08); border-bottom: 1px solid rgba(242,237,230,.08); }
.ev-fact { font-size: .82rem; letter-spacing: .04em; color: rgba(242,237,230,.72); }
.ev-fact.is-live { color: rgba(249,107,12,.95); letter-spacing: .06em; }
.ev-details-actions { padding-top: 16px; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ev-details-actions .ev-rsvp { padding: 11px 18px; }
/* PLAN 112 — SAVE beside RSVP: RSVP's bones and words, not the old icon square
   (.ev-save above is the retired sample card's). Lit = a soft cream fill, so it
   never reads as a second "Going". */
.ev-details-actions .ev-save {
  width: auto; height: auto; padding: 11px 18px; font: inherit; font-size: .64rem;
  letter-spacing: .2em; text-transform: uppercase; color: #f2ede6; white-space: nowrap;
  text-decoration: none; display: inline-block;
  transition: background 160ms, color 160ms, border-color 160ms;
}
.ev-details-actions .ev-save:hover { border-color: #f2ede6; }
.ev-details-actions .ev-save.is-saved { background: rgba(242,237,230,.12); border-color: rgba(242,237,230,.6); }
.ev-details-actions .ev-save:disabled { opacity: .6; cursor: default; }
.ev-fact.is-cancelled { color: #d97a6a; letter-spacing: .12em; text-transform: uppercase; font-size: .7rem; }
/* PLAN 112 — the date chips while Going / Saved is on: they do not apply. */
.ev-chips .chip:disabled { opacity: .35; cursor: default; }

/* the map half */
.ev-map { position: relative; min-width: 0; background: #0e0b09; }
/* `> .ev-map-canvas`, not `.ev-map-canvas`: MapLibre puts `.maplibregl-map`
   (position: relative) on its own container, its stylesheet is appended to the
   head AFTER this one, and at equal specificity the later rule wins — the box
   then collapses to zero height and the map is a black strip. Proven in the
   box's Chrome, 2026-09-21. */
.ev-map > .ev-map-canvas { position: absolute; inset: 0; }
.ev-map-note {
  position: absolute; left: 50%; top: 18px; transform: translateX(-50%); z-index: 2;
  margin: 0; max-width: min(90%, 420px); text-align: center;
  background: rgba(10,8,6,.88); border: 1px solid rgba(242,237,230,.12); padding: 10px 14px;
  font-size: .74rem; line-height: 1.5; letter-spacing: .04em; color: rgba(242,237,230,.7);
}
.ev-map-note[hidden] { display: none; }
/* MapLibre's own chrome, brought into the page's palette */
.ev-map .maplibregl-ctrl-group { background: #0a0806; border: 1px solid rgba(242,237,230,.14); box-shadow: none; }
.ev-map .maplibregl-ctrl-group button + button { border-top: 1px solid rgba(242,237,230,.14); }
.ev-map .maplibregl-ctrl-group button span { filter: invert(1) opacity(.7); }
.ev-map .maplibregl-ctrl-attrib { background: rgba(10,8,6,.7); }
.ev-map .maplibregl-ctrl-attrib a { color: rgba(242,237,230,.6); }

/* a pin. Cream dot; a live one wears the accent ring, the slow pulse and E13's
   count ("45", "99+") — the same three-places-one-number the app draws. */
.ev-pin { background: none; border: 0; padding: 0; cursor: pointer; display: block; line-height: 0; }
.ev-pin-dot {
  display: block; width: 14px; height: 14px; border-radius: 50%;
  background: #f2ede6; border: 2px solid #0a0806; box-shadow: 0 2px 6px rgba(0,0,0,.6);
  transition: transform 160ms, background 160ms;
}
.ev-pin:hover .ev-pin-dot, .ev-pin.is-active .ev-pin-dot { transform: scale(1.5); }
.ev-pin.is-active .ev-pin-dot { background: #fff; box-shadow: 0 0 0 4px rgba(242,237,230,.25); }
.ev-pin.is-live .ev-pin-dot { background: rgba(249,107,12,.95); animation: ev-pin-pulse 1.8s ease-in-out infinite; }
@keyframes ev-pin-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(249,107,12,.55); }
  50% { box-shadow: 0 0 0 8px rgba(249,107,12,0); }
}
.ev-pin-count {
  position: absolute; left: 14px; top: -10px;
  background: rgba(249,107,12,.95); color: #0a0806; border-radius: 9px;
  padding: 1px 5px; font-size: .58rem; font-weight: 800; letter-spacing: .04em; line-height: 1.5;
}
.ev-pin { position: relative; }

/* the "Map" chip is a narrow-screen affordance only: above the breakpoint the
   list and the map are both on screen and a swap would be a lie. */
.ev-map-chip { display: none; }

@media (max-width: 760px) {
  /* The shell's rows are auto-sized and `align-content` defaults to stretch, so
     a short view used to hand its leftover height to the RAIL — a phone showing
     two events got a 100px blank between the nav and the heading. Top-aligned
     is what every one of these views wants. (Found in the box's Chrome at
     400px, 2026-09-21.) */
  .app-shell { align-content: start; }
  .ev-view.is-active { display: block; height: auto; min-height: 0; }
  .ev-pane { border-right: 0; }
  .ev-head { padding: 22px 16px 0; }
  .ev-chips { padding: 0 16px 12px; }
  .ev-scroll, .ev-details { padding-left: 16px; padding-right: 16px; overflow: visible; }
  .ev-map { display: none; height: calc(100vh - 220px); min-height: 360px; }
  .ev-map-chip { display: inline-block; }
  .ev-view[data-pane="map"] .ev-map { display: block; }
  .ev-view[data-pane="map"] .ev-scroll, .ev-view[data-pane="map"] .ev-details { display: none; }
}

/* ---- PLAN 99 (lane W, 2026-09-22): Your details + Your orders ----------------
   No new colour and no new font: the cream, the near-black and the refusal red
   below are style.css's own, and the field boxes themselves come from
   `.wl-*` there — this page has always loaded both stylesheets. */

.app-shop { margin-top: auto; }
.app-side .app-shop {
  font-size: .62rem;
  letter-spacing: .24em;
  color: rgba(242, 237, 230, .55);
}
.app-side .app-shop:hover { color: #f2ede6; }

/* the bridge card (R11): an ask, so it looks like a card and not like a banner
   that has already decided something */
.det-bridge {
  max-width: 420px;
  border: 1px solid rgba(242, 237, 230, .16);
  background: rgba(242, 237, 230, .035);
  padding: 16px 18px;
  margin: 0 0 22px;
}
.det-bridge[hidden] { display: none; }
.det-bridge-line { margin: 0 0 14px; font-size: .88rem; letter-spacing: .04em; color: #f2ede6; }
.shop-save-row { display: flex; gap: 10px; flex-wrap: wrap; }

.det-privacy {
  max-width: 460px;
  font-size: .78rem;
  line-height: 1.6;
  letter-spacing: .03em;
  color: rgba(242, 237, 230, .6);
  margin-bottom: 24px;
}
.det-form .acct-h3:not(:first-child) { margin-top: 18px; }
.det-form .wl-fields { margin-bottom: 4px; }

/* Your orders */
.ord-list { list-style: none; margin: 0 0 18px; padding: 0; max-width: 520px; }
.ord-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 4px 14px;
  padding: 14px 0;
  border-bottom: 1px solid rgba(242, 237, 230, .1);
}
.ord-name { font-weight: 800; font-stretch: condensed; letter-spacing: .05em; font-size: 1rem; }
.ord-meta { grid-column: 1; display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: .74rem; letter-spacing: .08em; text-transform: uppercase; color: rgba(242, 237, 230, .5); }
.ord-state {
  grid-column: 2;
  grid-row: 1;
  align-self: start;
  font-size: .62rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(242, 237, 230, .75);
  border: 1px solid rgba(242, 237, 230, .2);
  padding: 4px 8px;
  white-space: nowrap;
}
.ord-state[data-state="failed"], .ord-state[data-state="cancelled"] { color: #d97a6a; border-color: rgba(217, 122, 106, .35); }
.ord-id { grid-column: 2; grid-row: 2; font-size: .62rem; letter-spacing: .14em; color: rgba(242, 237, 230, .35); text-align: right; }

@media (max-width: 720px) {
  .ord-row { grid-template-columns: 1fr; }
  .ord-state, .ord-id { grid-column: 1; grid-row: auto; text-align: left; justify-self: start; }
}

/* ---- ONE MENU (Red, 2026-09-22 ~04:15) — the drawer's ACCOUNT heading + its nested three */
.drawer-group-btn { background: none; border: 0; cursor: pointer; text-align: left; width: 100%; display: flex; align-items: center; justify-content: space-between; font-family: inherit; }
.drawer-caret { width: 8px; height: 8px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform 220ms ease; opacity: .7; }
.drawer-group.is-open .drawer-caret { transform: rotate(225deg); }
.drawer-group-links { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 260ms ease; }
.drawer-group-inner { overflow: hidden; min-height: 0; display: flex; flex-direction: column; gap: inherit; }
.drawer-group.is-open .drawer-group-links { grid-template-rows: 1fr; }
/* the three sit in their own box, so the slide-in stagger still counts them 1, 2, 3 */
.drawer-link.is-sub { padding-left: 18px; font-size: .9em; }
.drawer-link.is-active { color: #f2ede6; }

/* the map's credit line (2026-09-22): OpenStreetMap's licence wants the credit visible;
   MapLibre's "i" button is gone at Red's ask, so this quiet line carries it */
.ev-map { position: relative; }
.ev-map-credit { position: absolute; right: 8px; bottom: 6px; margin: 0; font-size: .55rem; letter-spacing: .04em; color: rgba(242,237,230,.45); pointer-events: none; }

/* the slide-in order with the Account row in it (Red, 2026-09-22 ~04:45: "the new account
   thing doesn't have that sliding animation"). RE-TIMED by plan 108 W5 (Red, 2026-09-23,
   who lifted the 09-15 motion freeze for exactly this) now Saved is gone: the same 55 ms
   step from the same 200 ms start, top to bottom, one row shorter —
   Events 200 · Messages 255 · Builds 310 (style.css's nth-child 1–3) · Account 365 ·
   its three 420/475/530 · Shop 585 · Home 640 */
html.menu-open .drawer-group .drawer-group-btn { transition-delay: 365ms; }
html.menu-open .drawer-group-inner .drawer-link:nth-child(1) { transition-delay: 420ms; }
html.menu-open .drawer-group-inner .drawer-link:nth-child(2) { transition-delay: 475ms; }
html.menu-open .drawer-group-inner .drawer-link:nth-child(3) { transition-delay: 530ms; }
html.menu-open .drawer-nav > .drawer-link:nth-child(5) { transition-delay: 585ms; }
html.menu-open .drawer-nav > .drawer-link:nth-child(6) { transition-delay: 640ms; }

/* ---- PLAN 100 W2 (2026-09-22) — the Referrals group on Your details ----------
   The bottom of the view, under its own rule, so it reads as its own thing and
   not as part of the details form above it (the Delete button belongs to that
   form, never to this). The look is the page's: the small caps heading, cream
   on black, the same @ box as every other handle on this site. */
.det-refs {
  max-width: 520px;
  margin-top: 34px;
  padding-top: 24px;
  border-top: 1px solid rgba(242, 237, 230, .1);
}
/* line one: the sentence, once a referrer is set (R5 — it never hides) */
.refs-line { margin: 0 0 18px; font-size: .92rem; letter-spacing: .04em; color: #f2ede6; }
.refs-line[hidden] { display: none; }
.refs-form { max-width: 420px; margin-bottom: 18px; }
.refs-form[hidden] { display: none; }
.refs-form .wl-fields { margin-bottom: 10px; }

/* line two: how many, then the names (R10 — names only, no credited mark) */
.refs-count { margin: 0 0 10px; font-size: .92rem; letter-spacing: .04em; color: #f2ede6; }
.refs-count[hidden] { display: none; }
.refs-list { list-style: none; margin: 0; padding: 0; }
.refs-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
  padding: 9px 0;
  border-bottom: 1px solid rgba(242, 237, 230, .08);
}
.refs-at { font-weight: 800; font-stretch: condensed; letter-spacing: .05em; font-size: .9rem; color: #f2ede6; }
.refs-sep, .refs-name { font-size: .82rem; letter-spacing: .03em; color: rgba(242, 237, 230, .6); }
.refs-more { padding: 9px 0; font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; color: rgba(242, 237, 230, .4); }
.refs-empty {
  max-width: 440px;
  margin: 0;
  font-size: .82rem;
  line-height: 1.6;
  letter-spacing: .03em;
  color: rgba(242, 237, 230, .55);
}
.refs-empty[hidden] { display: none; }

/* plan 102 (2026-09-24) — the account's one-line notices + the change-email
   waiting card. No new colours: the panel's cream, the error slot's red for a
   request that needs a decision. Bottom-left and fixed so the Events map never
   moves; it clears the messages button on the right. */
.acct-notices {
  position: fixed; left: 20px; bottom: 20px; z-index: 280;
  width: min(420px, calc(100% - 104px));
  display: flex; flex-direction: column; gap: 8px;
}
.acct-notices[hidden] { display: none; }
.acct-notice {
  background: #0a0806; border: 1px solid rgba(242,237,230,.18); padding: 12px 14px;
  font-size: .76rem; line-height: 1.5; letter-spacing: .04em; color: rgba(242,237,230,.85);
  animation: panel-in 220ms cubic-bezier(.2,.7,.2,1);
}
.acct-notice[data-kind="warn"] { border-color: rgba(217,122,106,.55); }
.acct-notice p { margin: 0; }
.acct-notice .acct-notice-links { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px 14px; }
.acct-notice a { color: #f2ede6; }
.acct-notice form { margin-top: 8px; }
.acct-waiting { list-style: none; margin: 10px 0 0; padding: 0; max-height: 45vh; overflow-y: auto; }
.acct-waiting li { padding: 8px 0; border-top: 1px solid rgba(242,237,230,.08); }
.acct-waiting li p { margin: 0; }
.email-wait { margin-top: 12px; border: 1px solid rgba(242,237,230,.14); padding: 14px 16px; }
.email-wait .panel-fine { text-transform: none; letter-spacing: .04em; font-size: .76rem; line-height: 1.5; margin: 0 0 8px; }
.acct-confirm .field-note + .field-note { margin-top: 6px; }
@media (max-width: 760px) {
  .acct-notices { left: 16px; bottom: 16px; width: calc(100% - 96px); }
}

/* ---- PLAN 110 (lane W, 2026-09-24): deactivate + the 30-day delete ---------
   · .acct-confirm-list — what deactivating does, one plain line each, inside
     the same red-edged confirm the delete uses.
   · .acct-away — the hidden account's one screen on the sign-in card ("Turn it
     back on" / "Reactivate" + Sign out). Same card, same fade, no new motion. */
.acct-confirm-list { margin: 0 0 14px; padding: 0 0 0 18px; font-size: .76rem; line-height: 1.5; letter-spacing: .04em; color: rgba(242,237,230,.75); }
.acct-confirm-list li + li { margin-top: 6px; }
.acct-away .panel-body:empty { display: none; }
.acct-away .panel-form { margin-top: 18px; }
.acct-away .panel-form .btn-ghost { padding: 12px 14px; }
