/* Control plane shell. Derived from samkoma-web's locked brand tokens, kept
   local because this authenticated app has a strict same-origin CSP and its own
   deploy lifecycle. */
:root {
  --cp-petrol: #157A78;
  --cp-petrol-deep: #0E5C5A;
  --cp-petrol-bright: #1FA39F;
  --cp-ink: #16202B;
  --cp-muted: #52606A;
  --cp-ember: #E7A85E;
  --cp-paper: #FFFFFF;
  --cp-soft: #F3F6F6;
  --cp-line: #E2E8E8;
  --cp-shell: 80rem;
  --cp-display: "Space Grotesk", "Segoe UI", sans-serif;
  --cp-body: "Inter", "Segoe UI", sans-serif;
  --cp-mono: "IBM Plex Mono", Consolas, monospace;
}

body.cp-page {
  background: var(--cp-paper);
  color: var(--cp-ink);
  font-family: var(--cp-body);
}

.cp-header {
  background: rgba(255, 255, 255, .94);
  border-bottom: 1px solid var(--cp-line);
  position: sticky;
  top: 0;
  z-index: 20;
}
.cp-header__inner {
  align-items: center;
  display: flex;
  gap: 1.25rem;
  justify-content: space-between;
  margin: 0 auto;
  max-width: var(--cp-shell);
  min-height: 4.5rem;
  padding: .75rem 1.5rem;
}
.cp-brand { align-items: center; color: var(--cp-ink); display: inline-flex; gap: .7rem; text-decoration: none; }
.cp-brand__mark { background: var(--cp-petrol); border-radius: 8px; box-shadow: inset 0 0 0 1px rgba(255,255,255,.28); height: 1.7rem; position: relative; width: 1.7rem; }
.cp-brand__mark::after { border: 2px solid #fff; border-left-color: transparent; border-radius: 50%; content: ""; inset: .34rem; position: absolute; transform: rotate(-28deg); }
.cp-brand__wordmark { font-family: var(--cp-display); font-size: 1.25rem; font-weight: 700; letter-spacing: .035em; }
.cp-brand__context { border-left: 1px solid var(--cp-line); color: var(--cp-muted); font-size: .78rem; font-weight: 600; letter-spacing: .1em; margin-left: .2rem; padding-left: .9rem; text-transform: uppercase; }
.cp-nav { align-items: center; display: flex; gap: .25rem; }
.cp-nav__link { border-radius: 8px; color: var(--cp-muted); font-size: .9rem; font-weight: 600; padding: .6rem .75rem; text-decoration: none; }
.cp-nav__link:hover, .cp-nav__link[aria-current="page"] { background: var(--cp-soft); color: var(--cp-petrol-deep); }

.cp-main { max-width: var(--cp-shell); padding: 3.5rem 1.5rem 4.5rem; }
.cp-main .reg { max-width: none; }
.cp-eyebrow { color: var(--cp-petrol); font-family: var(--cp-mono); font-size: .72rem; font-weight: 600; letter-spacing: .1em; margin: 0 0 .65rem; text-transform: uppercase; }
.cp-main .reg__title { color: var(--cp-ink); font-family: var(--cp-display); font-size: clamp(2rem, 4vw, 3.25rem); font-weight: 700; letter-spacing: -.045em; line-height: 1.03; max-width: 17ch; }
.cp-main .reg__lede { color: var(--cp-muted); font-size: 1.05rem; max-width: 62ch; }

/* Slice C: rehearsal-tenant "TEST" badge on the dashboard row so an operator never
   mistakes an Origin="test" tenant for a paying one. */
.data-table__test-badge { background: var(--cp-petrol); border-radius: 4px; color: #fff; display: inline-block; font-family: var(--cp-mono); font-size: .62rem; font-weight: 700; letter-spacing: .08em; margin-left: .4rem; padding: .1rem .35rem; text-transform: uppercase; vertical-align: middle; }

.cp-main .reg-form, .cp-main .registration-result, .cp-main .settings-event, .cp-main .data-table {
  background: var(--cp-paper);
  border-color: var(--cp-line);
  box-shadow: 0 12px 32px rgba(22, 32, 43, .06);
}
.cp-main .reg-form { border-radius: 14px; max-width: 38rem; }
.cp-main .reg-form__legend, .cp-main .field__label, .cp-main .settings-cell__label { color: var(--cp-ink); }
.cp-main .field__input, .cp-main .settings-cell__input, .cp-main .settings-cell__textarea, .cp-main .domain-cell input {
  border-color: #B9C8C8;
  border-radius: 8px;
}
.cp-main .field__input:focus, .cp-main .settings-cell__input:focus, .cp-main .settings-cell__textarea:focus, .cp-main .domain-cell input:focus {
  border-color: var(--cp-petrol); box-shadow: 0 0 0 3px rgba(21, 122, 120, .18);
}
.cp-main .btn { align-items: center; border-radius: 9px; display: inline-flex; justify-content: center; min-height: 2.75rem; letter-spacing: 0; }
.cp-main .btn--primary { background: var(--cp-petrol); color: #fff; }
.cp-main .btn--primary:hover { background: var(--cp-petrol-deep); }
.cp-main .btn--secondary { background: var(--cp-soft); border: 1px solid var(--cp-line); color: var(--cp-petrol-deep); }
.cp-main .btn--secondary:hover { background: #E8F1F1; border-color: var(--cp-petrol); }
.cp-main a:not(.cp-brand):not(.cp-nav__link) { color: var(--cp-petrol-deep); font-weight: 600; }
.cp-main code { background: var(--cp-soft); border-radius: 5px; color: var(--cp-ink); font-family: var(--cp-mono); font-size: .86em; padding: .15rem .32rem; }

.cp-main .data-table { border-collapse: separate; border-radius: 14px; border-spacing: 0; display: block; max-width: 100%; overflow-x: auto; }
.cp-main .data-table th { background: var(--cp-soft); color: var(--cp-muted); font-family: var(--cp-mono); font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; }
.cp-main .data-table td, .cp-main .data-table th { border-bottom-color: var(--cp-line); padding: 1rem; }
.cp-main .data-table tr:last-child td { border-bottom: 0; }
.cp-main .settings-event { border-radius: 14px; margin: 1.25rem 0; padding: 1.5rem; }
.cp-main .settings-event__title { color: var(--cp-ink); font-family: var(--cp-display); font-size: 1.35rem; margin: 0 0 1.25rem; }
.cp-main .settings-cell__hint, .cp-main .domain-cell__status { color: var(--cp-muted); }

/* THE SETTINGS FORMS HAD NO LAYOUT RULE AT ALL, in any stylesheet, ever.
   `.settings-cell` and `.settings-cell__form` were styled for colour and
   border only, so a <label> stayed inline and an <input> stayed inline-block
   and every field flowed into one running line: the class list, the fee, the
   Save button, the whole SMTP form and its checkbox, all on the same rows.

   THIS IS OLDER THAN MT-D-93. The classes/fee form has carried this class
   since D-PORTAL Part 2 section 7 and looked the same the whole time. It
   survived because /cp/admin sits behind CP auth and NOBODY HAD EVER OPENED
   THE AUTHENTICATED PAGE -- the browser pass recorded as owed since
   2026-08-10. Every gate stayed green over it: Go does not render CSS, and
   the new template-render test executes the markup, not the stylesheet.

   Matches `.field` in forms.css, which is what the rest of the site uses. */
.cp-main .settings-cell { display: flex; flex-direction: column; gap: var(--sp-3); }
.cp-main .settings-cell__form { display: flex; flex-direction: column; gap: var(--sp-1); }
/* A label stacks above its input -- EXCEPT the checkbox label, which must keep
   its box and its text on one line. flex+baseline does both. */
.cp-main .settings-cell__label { align-items: baseline; display: flex; gap: .5rem; margin-top: var(--sp-2); }
.cp-main .settings-cell__label:first-child { margin-top: 0; }
/* Inputs fill the column; buttons must NOT stretch to full width. */
.cp-main .settings-cell__input, .cp-main .settings-cell__textarea { width: 100%; }
.cp-main .settings-cell__form .btn { align-self: flex-start; margin-top: var(--sp-2); }
.cp-main .settings-cell__form p { margin: 0; }
/* A linked processor whose webhook never registered. Deliberately loud: the
   organizer is one click from taking card payments that can never confirm.
   Colour is not the only carrier -- the copy itself states the problem -- so
   this still reads correctly to a colour-blind or monochrome user. */
.cp-main .settings-cell__status--warn { background: #fff6e5; border: 1px solid #d98324; border-radius: 8px; color: #6b3b06; padding: .85rem 1rem; }
/* THE ERROR VARIANT HAD NO RULE, while --warn above did. So every failure this
   page reports -- a refused save, a rejected From address, the fail-closed
   "could not read your email settings" alert -- rendered as plain text,
   visually identical to a success message. The status classes carry the
   did-this-work signal and nothing was carrying it.
   Colour is not the only cue: the copy states the problem, and the elements
   are role="alert"/role="status", so this reads correctly without colour. */
.cp-main .settings-cell__status { border-radius: 8px; margin: 0; padding: .85rem 1rem; }
.cp-main .settings-cell__status--error,
/* The /cp twin, live-broken and invisible to the gate until 2026-08-12: it is
   only ever applied inside a {{if}}, and the class extractor skipped any
   attribute containing a brace. So a domain-assignment failure on /cp rendered
   exactly like a success. Same declaration as its /cp/admin sibling because it
   is the same signal. */
.cp-main .domain-cell__status--error { background: #fdecec; border: 1px solid #c0392b; color: #7d221a; }
.cp-setup-guide { background: var(--cp-soft); border: 1px solid var(--cp-line); border-radius: 14px; margin: 2rem 0; padding: 1.5rem; }
.cp-setup-guide h2 { font-family: var(--cp-display); font-size: 1.45rem; margin: 0 0 .4rem; }
.cp-setup-guide p { color: var(--cp-muted); margin: 0; max-width: 62ch; }
.cp-setup-guide__events { display: grid; gap: .85rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); margin-top: 1.25rem; }
.cp-setup-card { background: var(--cp-paper); border: 1px solid var(--cp-line); border-radius: 10px; padding: 1rem; }
.cp-setup-card h3 { font-family: var(--cp-display); font-size: 1rem; margin: 0 0 .75rem; }
.cp-setup-card ol { color: var(--cp-muted); line-height: 1.5; margin: 0; padding-left: 1.2rem; }
.cp-setup-card li + li { margin-top: .45rem; }
.cp-concierge-steps { display: grid; gap: .9rem; list-style: none; margin: 1.5rem 0; padding: 0; }
.cp-concierge-step { background: var(--cp-soft); border: 1px solid var(--cp-line); border-left: 4px solid #B9C8C8; border-radius: 10px; padding: 1.1rem 1.2rem; }
.cp-concierge-step.is-current { background: #EFFAF9; border-left-color: var(--cp-petrol); }
.cp-concierge-step.is-complete { border-left-color: #4C9B6C; }
/* SHOW DAY is reference, not a task: it has no done-state, so it must not borrow
   is-current (reads as "you still have to do this") or is-complete (reads as a task
   you finished). Its own neutral treatment, visually distinct from both. */
.cp-concierge-step.is-reference { background: #FBFAF6; border-left-color: #E7A85E; }
.cp-showday { margin: .6rem 0 .4rem; padding-left: 1.2rem; display: flex; flex-direction: column; gap: .55rem; }
.cp-showday li { line-height: 1.5; }
.cp-showday code { word-break: break-all; }
.cp-concierge-step.is-locked { opacity: .68; }
.cp-concierge-step h3 { font-family: var(--cp-display); font-size: 1.15rem; margin: 0 0 .45rem; }
.cp-concierge-step p { color: var(--cp-muted); margin: .35rem 0 .85rem; max-width: 60ch; }
.cp-concierge-step form { display: inline-block; margin: .25rem .45rem .25rem 0; }
/* Step 4 prints the event address as selectable text beneath the button, so an
   organizer can copy it to share without having to open the page first. */
.cp-concierge-url { margin: .6rem 0 0; }
.cp-concierge-url code { background: var(--cp-soft); border: 1px solid var(--cp-line); border-radius: 6px; display: inline-block; padding: .35rem .55rem; word-break: break-all; }
.cp-main .registration-result--success { background: #EFFAF4; border-color: #74B990; }
.cp-main .registration-result--error { background: #FFF4F2; border-color: #DE8C83; }

.cp-footer { background: var(--cp-ink); border: 0; color: #C8D4D8; padding: 1.5rem; text-align: left; }
.cp-footer__inner { display: flex; font-size: .82rem; justify-content: space-between; margin: 0 auto; max-width: var(--cp-shell); }
.cp-footer p { margin: 0; }
.cp-footer__label { color: var(--cp-ember); font-family: var(--cp-mono); letter-spacing: .08em; text-transform: uppercase; }

@media (max-width: 38rem) {
  .cp-header__inner { padding-inline: 1rem; }
  .cp-brand__context { display: none; }
  .cp-nav__link { padding-inline: .55rem; }
  .cp-main { padding: 2.25rem 1rem 3rem; }
  .cp-main .settings-event { padding: 1rem; }
  .cp-footer__inner { align-items: flex-start; flex-direction: column; gap: .35rem; }
}

@media (prefers-reduced-motion: reduce) {
  .cp-main *, .cp-header * { transition: none !important; }
}

/* ---------------------------------------------------------------------------
   CREW GUIDES: SCREEN CHROME vs PRINTED SHEETS.

   /cp/guides promises "hand each person only their own sheet". There was NO
   @media print rule anywhere under web/static/css/, so Print produced ONE
   continuous document -- site header and nav, the address card, "before you
   print", then all five roles run together with no page break between them.
   The organizer had to cut it up by hand, at the exact moment they have least
   time to.

   .cp-screen-only is the organizer's half of the page (chrome, intro, address
   card, notes, the back-links). .cp-guide-sheet is one crew member's sheet.
   --------------------------------------------------------------------------- */
.cp-guide-sheet__addr { color: var(--cp-muted); margin: 0 0 .9rem; }
.cp-guide-sheet__addr code { word-break: break-all; }

/* THE FILL-IN RULE. These sheets printed the literal text "[name / number]" sixteen
   times, and the only instruction explaining it sat on a cp-screen-only card that
   does NOT print -- so a volunteer was told sixteen times to go and find a bracket.
   claims-lint ruled it not publishable; the organizer's own words were that a
   half-filled sheet is worse than an empty one, because a real address at the top
   makes the rest read as finished.
   A ruled blank is self-explanatory on paper and cannot be mistaken for content. */
.cp-fill {
  display: inline-block;
  min-width: 14rem;
  border-bottom: 1px solid currentColor;
  vertical-align: baseline;
}
.cp-fill-hint { color: var(--cp-muted); font-size: .85em; }
@media print { .cp-fill-hint { display: none; } }

@media print {
  /* Everything that belongs to the organizer, not to the person at the gate. */
  .cp-screen-only, .skip-link { display: none !important; }

  body.cp-page { background: #fff; color: #000; font-size: 10.5pt; }
  .cp-main { max-width: none; padding: 0; }
  .cp-main .reg { max-width: none; }
  .cp-main a { color: #000; font-weight: 600; text-decoration: none; }
  .cp-main code { background: transparent; border: 0; padding: 0; }

  /* ONE ROLE PER PAGE. The five sheets are ADJACENT siblings, so the adjacent
     combinator breaks between them without also throwing a blank first page --
     :first-of-type would not work here, because display:none does not stop the
     screen-only <article>s counting as earlier articles of the same type. */
  .cp-guide-sheet {
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
  }
  .cp-guide-sheet + .cp-guide-sheet {
    page-break-before: always; /* legacy alias kept for older print engines */
    break-before: page;
  }
  /* Keep a heading with the block it introduces; a role heading alone at the
     foot of a page is how a crew sheet loses its first instruction. */
  .cp-guide-sheet h2, .cp-guide-sheet h3 { page-break-after: avoid; break-after: avoid; }
  .cp-guide-sheet li, .cp-guide-sheet p { page-break-inside: avoid; break-inside: avoid; }
  .cp-guide-sheet__addr {
    border: 1px solid #000;
    border-radius: 4px;
    color: #000;
    padding: .3rem .5rem;
  }
  /* The show-day step block is a plain list on paper. */
  .cp-showday { gap: .3rem; }
}
