/* The operator's STANDALONE pages: login, the magic-link and invite flows, the
   password pages, the branded error page and the public booking page. Linked
   by each of them through theme_css('auth'), AFTER the page's own inline
   <style>, and only when this file is on disk.

   Black is the canvas, white is the signal, orange is the spark. Orange is
   never a resting fill, which is why the primary action is an outlined ember
   capsule rather than a solid slab.

   HOW THIS FILE WINS, and why it is mostly variables.

   Every one of these pages is a standalone document carrying its own inline
   :root of the same eight or nine names (--bg, --panel, --ink, --body,
   --muted, --line, --line-strong, --danger, --danger-bg) plus the --primary
   group from partials/_accent.html. So the first block below restates those
   names at the same specificity and later in the cascade, and the whole page
   re-themes: the booking page's type cards, the error page's panel and the
   2FA pages' fields all read those names already and none of them needs a
   rule here. Only the shapes the look actually changes are written out.

   THE TWO VARIABLE BLOCKS MUST STAY IN SYNC. templates/set_password.html
   carries its own dark block at :root[data-theme="dark"], which is (0,1,1)
   and beats a plain :root whatever the load order, and it always stamps the
   attribute before paint. So the same list is written twice: once bare, once
   behind [data-theme], which ties with that page's own selector and wins on
   source order. Change one, change both.

   The accent itself is NOT here. partials/_accent.html resolves --primary from
   the identity's theme slug, so the ember reaches these pages through the
   same partial the estate's own ink does, and this file never restates it. */

@font-face {
  font-family: 'Nohemi';
  src: url('fonts/Nohemi-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Nohemi';
  src: url('fonts/Nohemi-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Nohemi';
  src: url('fonts/Nohemi-SemiBold.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
/* The technical voice: labels, meta and codes. */
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/JetBrainsMono-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}


/* ─── The palette. Block 1: every page. ──────────────────────────────────
   Measured on the card ground: #F9F9F9 is 18.8:1, #A7A7A7 is 8.23:1, and
   #8A8A8A is 5.34:1 on the field. Nothing below #8A8A8A carries text.
   The last four names belong to set_password.html only; harmless elsewhere.
   ─────────────────────────────────────────────────────────────────────── */
:root {
  --bg: #000000;
  --panel: #0A0A0A;
  --raised: #141414;
  --ink: #F9F9F9;
  --body: #F9F9F9;
  --muted: #A7A7A7;
  --placeholder: #8A8A8A;
  --line: #262626;
  --line-strong: #3A3A3A;
  --danger: #FF6B5A;
  --danger-bg: rgba(255, 107, 90, .10);
  --card: #0A0A0A;
  --field: #141414;
  --border: #262626;
  --ok: #6FCF97;
  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --ls-cta: .14em;
  color-scheme: dark;
}

/* ─── Block 2: the same list, behind the attribute. ──────────────────────
   See the header. This exists for set_password.html, which stamps data-theme
   before paint and carries its own (0,1,1) dark block.
   ─────────────────────────────────────────────────────────────────────── */
:root[data-theme] {
  --bg: #000000;
  --panel: #0A0A0A;
  --raised: #141414;
  --ink: #F9F9F9;
  --body: #F9F9F9;
  --muted: #A7A7A7;
  --placeholder: #8A8A8A;
  --line: #262626;
  --line-strong: #3A3A3A;
  --danger: #FF6B5A;
  --danger-bg: rgba(255, 107, 90, .10);
  --card: #0A0A0A;
  --field: #141414;
  --border: #262626;
  --ok: #6FCF97;
  color-scheme: dark;
}


/* ─── The ground, and the grain. ─────────────────────────────────────────
   Film grain is the texture the brand reads by, and it is what stops a dark
   page looking like a dark admin panel. Painted on body::after rather than on
   an element, because these pages have no wrapper in common and none of them
   uses that pseudo-element today. Fixed and pointer-events:none, so it never
   scrolls away from the card and never eats a click.
   ─────────────────────────────────────────────────────────────────────── */
body {
  /* At least the viewport, so a short page (a booking step, the expired-link
     card) carries the gradient to the bottom edge rather than stopping under
     its own content on a flat black html ground. */
  min-height: 100vh;
  background: linear-gradient(180deg, #000000 0%, #1A0703 60%, #3A1304 100%);
  background-attachment: fixed;
  color: var(--body);
  font-family: 'Nohemi', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: .06;
  mix-blend-mode: overlay;
  z-index: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
}

/* The card sits above the grain. Both wrappers, because login and its family
   use .auth-card and the booking and error pages use .wrap. */
.auth-page, .auth-card, .wrap, .card { position: relative; z-index: 1; }


/* ─── The card. ──────────────────────────────────────────────────────────
   Squarer than the estate's, on a near-black ground, with the shadow doing
   the lifting rather than a border colour.
   ─────────────────────────────────────────────────────────────────────── */
.auth-card {
  border-radius: 12px;
  padding: 38px 34px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .55), 0 1px 0 rgba(255, 255, 255, .04) inset;
}

@media (max-width: 420px) {
  .auth-card { padding: 30px 22px; }
}


/* ─── The mark. ──────────────────────────────────────────────────────────
   The estate's .brand-chip draws a dark slab behind the wordmark because that
   artwork is light-on-dark and would be invisible on a white card. This look
   has no white card and the mark is already white on black, so the chip has
   nothing left to do: transparent, borderless, no padding, and the mark grows
   to the size it is drawn at.
   ─────────────────────────────────────────────────────────────────────── */
.brand-chip {
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
}

.brand-chip img { height: 46px; }

.brand-header .brand-chip img { height: 30px; }

/* The eyebrow under the mark: the technical voice, tracked out. */
.auth-logo .kicker,
.brand-header .brand-kicker {
  font: 400 11px/1 var(--mono);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}


/* ─── Fields. ────────────────────────────────────────────────────────────
   16px on the input, not 15: below 16 iOS Safari zooms the page on focus.
   Labels take the mono voice; the checkbox label beside "Remember this
   device" is running text and opts back out below.
   ─────────────────────────────────────────────────────────────────────── */
.field label,
.card label {
  font: 400 11px/1 var(--mono);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}

.auth-input,
.card input {
  min-height: 52px;
  padding: 13px 16px;
  background: var(--raised);
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  color: var(--ink);
  font-size: 16px;
  caret-color: var(--primary);
}

.auth-input::placeholder,
.card input::placeholder { color: var(--placeholder); }

.auth-input:focus,
.card input:focus {
  outline: none;
  border-color: var(--primary);
  background: #171717;
  box-shadow: 0 0 0 1px var(--primary);
}

/* Autofill paints its own ground; without this the field goes pale blue. */
.auth-input:-webkit-autofill {
  -webkit-box-shadow: inset 0 0 0 1000px var(--raised);
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--primary);
}

/* The 2FA code: one glyph at a time, spaced out, in the technical voice. */
#totp-code {
  font-family: var(--mono);
  font-size: 22px;
  text-align: center;
  letter-spacing: .4em;
}

.pw-wrap .auth-input,
.pw-wrap input { padding-right: 68px; }

/* Muted, not orange: one spark per view, and the capsule owns it. */
.pw-toggle,
.peek {
  color: var(--muted);
  font: 400 11px var(--mono);
  letter-spacing: .1em;
  text-transform: uppercase;
}

.pw-toggle { padding: 0 14px; }
.pw-toggle:hover, .peek:hover { color: var(--ink); }


/* ─── The ember capsule. ─────────────────────────────────────────────────
   Orange stays a spark: an outline at rest, filling only on hover, where the
   ink flips to near-black because white on the ember measures 3.58:1 and
   fails while near-black measures 5.26:1 and passes.
   ─────────────────────────────────────────────────────────────────────── */
.btn-primary,
button.submit {
  min-height: 54px;
  padding: 15px 20px;
  background: transparent;
  color: var(--primary);
  border: 1px solid var(--primary);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: var(--ls-cta);
  text-transform: uppercase;
  transition: background .16s ease, color .16s ease, box-shadow .16s ease;
}

.btn-primary:hover:not(:disabled),
button.submit:hover:not(:disabled) {
  background: var(--primary);
  color: var(--primary-inverse);
  box-shadow: 0 0 32px rgba(232, 80, 2, .18), 0 0 80px rgba(193, 8, 1, .10);
}

.btn-primary:active:not(:disabled) {
  background: var(--primary-700);
  border-color: var(--primary-700);
  color: var(--primary-inverse);
}

.btn-primary:disabled,
button.submit:disabled { opacity: .45; }

.btn-primary:focus-visible,
button.submit:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--primary);
}

/* One primary, one ghost. Three identical slabs read as an admin panel. */
.btn-ghost {
  min-height: 50px;
  padding: 13px 18px;
  background: transparent;
  color: var(--body);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .08em;
  text-transform: uppercase;
  transition: border-color .14s ease, color .14s ease;
}

.btn-ghost:hover {
  background: transparent;
  border-color: #5A5A5A;
  color: var(--ink);
}

.btn-ghost:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--primary);
}


/* ─── Running text that must NOT take the mono voice. ────────────────────
   The remember-device label and the notices are sentences, not labels.
   ─────────────────────────────────────────────────────────────────────── */
/* The login page's checkbox reads the estate's cool periwinkle (--cool),
   which this look has no use for. */
.remember input { accent-color: var(--primary); }

.remember label {
  font-family: inherit;
  font-size: 13px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--muted);
}

.login-error {
  border-radius: 10px;
  border-color: rgba(255, 107, 90, .32);
}

.twofa-hint, #magic-sent, .hint, .sub, .intro { color: var(--muted); }

#magic-section { border-top-color: var(--line); }

::selection { background: var(--primary); color: var(--primary-inverse); }


/* ─── The status names, on this ground. ──────────────────────────────────
   The booking steps (book/reserve, confirmed, manage, cancelled) and the
   reset page declare --good, --warning and their grounds as tints mixed for a
   white card, so on this card a confirmation sat in a pale green disc. The
   same values the cockpit's dark block uses for its own status colours.
   ─────────────────────────────────────────────────────────────────────── */
:root {
  --good: #6FCF97;
  --good-bg: rgba(111, 207, 151, .12);
  --warning: #F2C94C;
  --warning-bg: rgba(242, 201, 76, .12);
  --neutral: #A7A7A7;
}

/* The booked time on book/reserve.html reads --primary-700, a shade mixed to
   darken on white; on this card that is 2.9:1. The ember itself is 5.26:1. */
.card .when { color: var(--primary); }

/* The "processing" disc on book/confirmed.html is a literal pale blue. */
.icon-badge.processing { background: rgba(var(--primary-rgb), .12); }

/* book/reserve.html wraps each field in its label, so the label's mono voice
   above would reach the typed value through the field's `font: inherit`. The
   value is running text and takes the page face back. */
.card label > input,
.card label > select {
  font-family: 'Nohemi', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  letter-spacing: normal;
  line-height: 1.4;
}


/* ─── The connector consent page. ────────────────────────────────────────
   oauth_consent.html paints Approve as a slab of --ink under white text, which
   on this palette is white on near-white. Approve takes the ember capsule the
   sign-in page's primary action wears; Cancel stays the quiet ghost.
   ─────────────────────────────────────────────────────────────────────── */
.consent-card {
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .55), 0 1px 0 rgba(255, 255, 255, .04) inset;
}

.consent-btn {
  min-height: 50px;
  background: transparent;
  color: var(--body);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 13px;
  letter-spacing: .08em;
  text-transform: uppercase;
}

.consent-btn--primary {
  background: transparent;
  color: var(--primary);
  border-color: var(--primary);
  letter-spacing: var(--ls-cta);
}

.consent-btn--primary:hover {
  background: var(--primary);
  color: var(--primary-inverse);
}

.consent-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--primary);
}


/* ─── The privacy policy. ────────────────────────────────────────────────
   templates/privacy.html stamps data-surface="privacy" and paints its section
   headings in the estate's red through --accent, which no other page linking
   this file declares. The ember, which measures 5.26:1 on this ground.
   ─────────────────────────────────────────────────────────────────────── */
html[data-surface="privacy"] {
  --accent: #E85002;
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .001ms !important; }
}
