/* Handsome Hosting — brand application (V1, 2026-07-11).
   All values come from /static/tokens.css (the vendored brand book tokens).
   No ad-hoc colors: if a color is not a token, it does not belong here
   (single deliberate exception: the functional error red, marked below). */

/* Self-hosted fonts (Heebo + Inter, hebrew + latin subsets only).
   Each family's hebrew/latin subset is a single variable-weight woff2;
   the same file backs the 400/600/700 declarations below (mirrors the
   @font-face blocks Google Fonts itself serves for these families). */
@font-face {
  font-family: 'Heebo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/NGS6v5_NC0k9P9H0TbFzsQ.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: 'Heebo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/NGS6v5_NC0k9P9H0TbFzsQ.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: 'Heebo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/NGS6v5_NC0k9P9H0TbFzsQ.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: 'Heebo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/NGS6v5_NC0k9P9H2TbE.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Heebo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/NGS6v5_NC0k9P9H2TbE.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Heebo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/NGS6v5_NC0k9P9H2TbE.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/UcC73FwrK3iLTeHuS_nVMrMxCp50SjIa1ZL7.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Departure-Board faces (design go-live 2026-08-03), self-hosted woff2 —
   NO CDN / Google Fonts request on any page. Subsets and unicode-ranges mirror
   what Google Fonts serves for these families (hebrew + latin only; the other
   subsets are dropped). Secular One ships a single 400 weight by construction
   (do not synthesize bold). Assistant is one variable woff2 per subset spanning
   400–700. IBM Plex Mono is Latin-only — it has NO Hebrew glyphs, so Hebrew
   text must never be routed through --font-mono (see the Hebrew-mono caveat). */
@font-face {
  font-family: 'Secular One';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/secular-one-hebrew.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: 'Secular One';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/secular-one-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Assistant';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/assistant-hebrew.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: 'Assistant';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/assistant-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/static/fonts/ibm-plex-mono-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

* { box-sizing: border-box; }
html { line-height: var(--lh-normal); }
body {
  margin: 0;
  font-family: var(--font-stack);
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);
  color: var(--text-default);
  background: var(--surface-page);
}

/* Accessibility */
.skip-link {
  position: absolute; inset-inline-start: -9999px;
  background: var(--color-navy); color: var(--color-white);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm);
}
.skip-link:focus { inset-inline-start: var(--space-2); top: var(--space-2); z-index: 10; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* Shell */
.site-header { border-block-end: 1px solid var(--color-border); background: var(--surface-page); }
.site-header-inner {
  max-width: 60rem; margin-inline: auto;
  padding: var(--space-3) var(--space-4);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-4);
}
/* WO-4: drive the lockup's navy strokes/wordmark via currentColor so they flip
   with the theme (ink on the light header, white on the dark navy header) —
   overriding the global link color, since .brand-lockup is an <a>. The accent
   crossbar/subtitle keep the fixed brand accent (legible on both surfaces). */
/* First Light lockup: star + "Handsome Hosting" wordmark. The wordmark inherits
   the header text color via currentColor (--text-default flips ink/cream with
   the theme); the star fills --brand-star (gold on night, deeper gold on cream).
   No hardcoded navy. The AH monogram + its draw-on motion were retired in the
   restyle (R2). */
.brand-lockup { display: inline-flex; align-items: center; color: var(--text-default); }
.brand-lockup img, .brand-lockup svg { display: block; }

main.page {
  max-width: 60rem; margin-inline: auto;
  padding: var(--space-6) var(--space-4) var(--space-8);
  display: flex; flex-direction: column; gap: var(--space-6);
}
.site-footer {
  border-block-start: 1px solid var(--color-border);
  max-width: 60rem; margin-inline: auto;
  padding: var(--space-4); display: flex; gap: var(--space-4); flex-wrap: wrap;
  align-items: baseline;
  color: var(--text-default); font-size: var(--fs-eyebrow);
}
.site-footer a { color: var(--text-default); }
.site-footer a:hover { color: var(--link); }

/* Type */
h1 { font-size: var(--fs-h1); font-weight: var(--fw-bold); line-height: var(--lh-tight); letter-spacing: var(--ls-tight); margin: 0; }
h2 { font-size: var(--fs-h3); font-weight: var(--fw-bold); line-height: var(--lh-tight); margin: var(--space-4) 0 0; }
h3 { font-size: var(--fs-h3card); font-weight: var(--fw-bold); margin: 0; }
p, li { max-width: 65ch; }
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
.eyebrow {
  color: var(--link); font-size: var(--fs-eyebrow); font-weight: var(--fw-semibold);
  text-transform: uppercase; letter-spacing: var(--ls-eyebrow);
}
[dir='rtl'] .eyebrow { letter-spacing: 0; } /* Hebrew has no uppercase; wide tracking hurts it */

/* First Light hero — one continuous sky (brief §4/§6). Night + headline up top,
   dawn + the rising north star at the bottom; the sky is a CSS gradient that
   fills the container at any width, so the dawn is always visible (never a
   sliced image). Light theme is "daylight after the dawn" (§9): warm cream with
   a low gold glow and faint stars. Landing is always RTL: content right-aligned,
   the primary CTA on the right with the ghost link to its left. */
.sky-scene {
  position: relative; isolation: isolate; overflow: hidden;
  border-radius: var(--radius-lg);
  min-height: 32rem;
  padding: var(--space-8) var(--space-6) 11rem;
  display: flex; flex-direction: column;
  /* Light (daylight-after-dawn) is the base; dark overrides below. */
  background: linear-gradient(180deg,
    var(--color-cream) 0%, var(--color-cream) 50%, #F7E9CE 74%, var(--dawn-gold) 100%);
  color: var(--text-default);
}
.sky-dawn {
  position: absolute; left: 0; right: 0; bottom: 0; height: 15rem; z-index: 0;
  pointer-events: none; transform-origin: bottom center; opacity: .5;
  background: radial-gradient(ellipse 70% 100% at 50% 100%,
    var(--star-gold-glow) 0%, rgba(233,165,112,.28) 45%, transparent 74%);
  animation: dawn-breathe 4s ease-in-out infinite;
}
.sky-horizon {
  position: absolute; left: 0; right: 0; bottom: 9.5rem; height: 1px; z-index: 0;
  pointer-events: none; opacity: .45;
  background: linear-gradient(90deg, transparent, var(--star-gold-glow) 30%, var(--star-gold-glow) 70%, transparent);
}
.sky-stars {
  position: absolute; top: 0; left: 0; right: 0; height: 64%; z-index: 0;
  pointer-events: none; opacity: .28;
}
.sky-stars .stars-cream { fill: var(--muted-blue); }
.sky-stars .stars-gold { fill: var(--star-on-light); }
.sky-stars .tw { animation: star-twinkle 2.2s ease-in-out infinite; }
.sky-northstar {
  position: absolute; left: 50%; bottom: 9.5rem; z-index: 1;
  transform: translate(-50%, 50%);
  animation: north-pulse 2.6s ease-in-out infinite;
}
.northstar-glow {
  position: absolute; left: 50%; top: 50%; width: 9rem; height: 9rem;
  margin: -4.5rem 0 0 -4.5rem; border-radius: 50%; pointer-events: none; opacity: .6;
  background: radial-gradient(circle, var(--star-gold-soft), transparent 68%);
  animation: north-glow 2.6s ease-in-out infinite;
}
.sky-northstar > svg { position: relative; display: block; }

/* Hero content floats on the sky (break the boxes). */
.hero-content {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; gap: var(--space-3);
  align-items: flex-start; max-width: 40rem;
}
.hero-content h1 {
  color: var(--text-default); margin: var(--space-2) 0 0;
  font-size: clamp(1.95rem, 5.5vw, 2.8rem); line-height: 1.12;
  text-shadow: 0 2px 30px rgba(4,8,20,.35);
}
.hero-gloss { color: var(--text-muted); font-size: var(--fs-eyebrow); direction: ltr; text-align: right; }
.hero-sub { color: var(--text-default); opacity: .9; max-width: 36ch; line-height: var(--lh-normal); }
.hero-cta { display: flex; align-items: center; gap: var(--space-4); margin-top: var(--space-2); flex-wrap: wrap; }
.sky-scene .btn-sun {
  background: linear-gradient(180deg, var(--cta-gold), var(--cta-amber));
  color: var(--cta-ink); border: none;
  animation: cta-glow 2.4s ease-in-out infinite;
}
.sky-scene .btn-sun:hover { filter: brightness(1.03); }
.ghost-link {
  display: inline-flex; align-items: center; gap: var(--space-2);
  color: var(--text-default); font-weight: var(--fw-bold); text-decoration: none;
}
.sky-scene .status-chip { color: var(--text-default); margin-top: var(--space-2); }

/* Dark theme = the full celestial night sky. */
:root[data-theme='dark'] .sky-scene {
  background: linear-gradient(180deg,
    var(--night-900) 0%, var(--night-800) 30%, var(--night-700) 52%, var(--twilight-600) 70%,
    var(--dawn-rose-deep) 82%, var(--dawn-rose) 90%, var(--dawn-amber) 96%, var(--dawn-gold) 100%);
}
:root[data-theme='dark'] .sky-dawn { opacity: .85; }
:root[data-theme='dark'] .sky-horizon { opacity: .6; }
:root[data-theme='dark'] .sky-stars { opacity: 1; }
:root[data-theme='dark'] .sky-stars .stars-cream { fill: var(--cream); }
:root[data-theme='dark'] .sky-stars .stars-gold { fill: var(--star-gold); }
:root[data-theme='dark'] .northstar-glow { opacity: .85; }
:root[data-theme='dark'] .hero-content h1 { color: var(--cream-bright); }
:root[data-theme='dark'] .hero-sub { color: var(--muted-violet); opacity: 1; }
:root[data-theme='dark'] .ghost-link { color: var(--star-gold-soft); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .sky-scene {
    background: linear-gradient(180deg,
      var(--night-900) 0%, var(--night-800) 30%, var(--night-700) 52%, var(--twilight-600) 70%,
      var(--dawn-rose-deep) 82%, var(--dawn-rose) 90%, var(--dawn-amber) 96%, var(--dawn-gold) 100%);
  }
  :root:not([data-theme]) .sky-dawn { opacity: .85; }
  :root:not([data-theme]) .sky-horizon { opacity: .6; }
  :root:not([data-theme]) .sky-stars { opacity: 1; }
  :root:not([data-theme]) .sky-stars .stars-cream { fill: var(--cream); }
  :root:not([data-theme]) .sky-stars .stars-gold { fill: var(--star-gold); }
  :root:not([data-theme]) .northstar-glow { opacity: .85; }
  :root:not([data-theme]) .hero-content h1 { color: var(--cream-bright); }
  :root:not([data-theme]) .hero-sub { color: var(--muted-violet); opacity: 1; }
  :root:not([data-theme]) .ghost-link { color: var(--star-gold-soft); }
}
@media (max-width: 40rem) {
  .sky-scene { padding: var(--space-6) var(--space-4) 9rem; min-height: 28rem; }
}

@keyframes star-twinkle { 0%, 100% { opacity: .9; } 50% { opacity: .18; } }
@keyframes north-pulse { 0%, 100% { transform: translate(-50%, 50%) scale(1); } 50% { transform: translate(-50%, 50%) scale(1.16); } }
@keyframes north-glow { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.22); } }
@keyframes dawn-breathe { 0%, 100% { transform: scaleY(1); } 50% { transform: scaleY(1.08); } }
@keyframes cta-glow { 0%, 100% { box-shadow: 0 0 24px rgba(233,178,120,.4); } 50% { box-shadow: 0 0 52px rgba(233,178,120,.8); } }

/* Hero status chip (H1, BINDING): shows an illustrative STATE — the word
   LIVE + a live dot — never a fabricated telemetry figure (no uptime %,
   no response time, no invented number). Sits on the fixed-navy hero
   surface in both themes, so the green "LIVE" text clears AA there; if a
   status label like this is ever needed on a near-white surface, render the
   label in --text-default and keep only the dot green (see brief). */
.status-chip {
  display: inline-flex; align-items: center; gap: var(--space-2);
  align-self: flex-start;
  color: var(--text-on-panel);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-4);
  font-size: var(--fs-eyebrow); font-weight: var(--fw-semibold);
}
.status-chip-live { color: var(--signal-live); }
.live-dot {
  display: inline-block;
  inline-size: 8px; block-size: 8px; flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: var(--signal-live);
  animation: live-pulse 2s ease-in-out infinite;
}
@keyframes live-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

/* Warm section (cream surface) */
/* TA-5 dark-legibility fix: --surface-warm is a theme-invariant fixed cream
   (like the hero's fixed navy). This rule previously set no text color, so
   it inherited --text-default — white in dark theme, on a fixed-light
   background = ~1.1:1, invisible. --text-on-warm is the symmetric
   theme-invariant counterpart to the hero's --text-on-dark: fixed dark ink,
   correct because cream is light in both themes (~17.3:1 either way — see
   task report). Hits both the landing pricing teaser and the waitlist
   fallback section, which share this class. */
.section-warm {
  background: var(--surface-warm);
  color: var(--text-on-warm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
}
/* R6 a11y: --surface-warm is a theme-invariant fixed cream, so links inside it
   must use the fixed dark-on-cream link (--link-on-light, ~5.4:1) — NOT the
   theme --link, whose dark-theme value (starlight-blue) is only 2.46:1 on cream.
   Same fixed-surface-meets-theme-color fix as --text-on-warm did for body text. */
.section-warm a { color: var(--link-on-light); }

/* Cards */
.card {
  background: var(--surface-raised); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-card);
  padding: var(--space-6);
}
.card-row { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); margin: var(--space-4) 0 0; padding: 0; }
ol.card-row { list-style: none; counter-reset: steps; }
ol.card-row > li { counter-increment: steps; }
ol.card-row > li::before {
  content: counter(steps);
  display: inline-flex; align-items: center; justify-content: center;
  inline-size: var(--space-8); block-size: var(--space-8);
  border-radius: var(--radius-pill);
  background: var(--color-navy); color: var(--color-white);
  font-weight: var(--fw-bold); margin-block-end: var(--space-3);
}
ol.card-row > li { display: flex; flex-direction: column; }

/* "How it works" — the rising constellation (brief §4): three steps as stars
   climbing a faint dashed arc toward "live". Star vocabulary is locked from R3
   (blue for the quiet stars, gold for the precious last one). RTL-first: the
   journey starts bottom-right ("אתה בונה") and climbs to the top-left gold star
   ("וזה באוויר"). On load the arc draws in and the steps rise, staggered;
   everything holds still under prefers-reduced-motion. Stacks vertically under
   40rem (arc hidden), no overflow. */
.constellation-section .const-row {
  position: relative; display: flex; direction: rtl;
  justify-content: space-between; align-items: flex-start;
  gap: var(--space-4); margin-block-start: var(--space-8);
}
.const-arc {
  position: absolute; inset-inline: 0; inset-block-start: 0;
  block-size: 7.5rem; inline-size: 100%; pointer-events: none;
  animation: const-draw 1.2s ease-out .3s both;
}
.node {
  flex: 1; min-inline-size: 0; text-align: center; position: relative;
  animation: node-rise .7s ease-out both;
}
.node .node-label { color: var(--text-default); font-weight: var(--fw-bold); margin-block-start: var(--space-2); }
.node .node-caption { color: var(--text-muted); font-size: var(--fs-eyebrow); margin-block-start: var(--space-1); line-height: 1.45; }
.star-ico { filter: drop-shadow(0 0 7px rgba(233,200,122,.5)); }
.node-1 { margin-block-start: 4rem; animation-delay: .15s; }
.node-2 { margin-block-start: 2rem; animation-delay: .4s; }
.node-3 { margin-block-start: 0; animation-delay: .65s; }
@media (max-width: 40rem) {
  .constellation-section .const-row { flex-direction: column; align-items: center; gap: var(--space-6); }
  .node { margin-block-start: 0 !important; inline-size: 100%; }
  .const-arc { display: none; }
}
@keyframes const-draw { from { opacity: 0; } to { opacity: .5; } }
@keyframes node-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }

/* Trust section ("נשאר שלכם") — quiet hierarchy: a hairline divider instead
   of a bordered panel, instrument register rather than another card. */
.trust-panel {
  border-block-start: 1px solid var(--border-subtle);
  padding-block-start: var(--space-6);
}

/* Buttons */
.btn, button {
  display: inline-block; cursor: pointer;
  background: var(--color-accent); color: var(--color-white);
  font-family: var(--font-stack); font-size: var(--fs-body); font-weight: var(--fw-semibold);
  border: 0; border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-6);
}
.btn:hover, button:hover { filter: brightness(0.92); text-decoration: none; }
/* Auth basics sweep: quiet inline controls (signout, verify resend, remember-me). */
.btn-quiet { background: transparent; color: var(--text-muted); border: 1px solid var(--border-subtle); box-shadow: none; }
.auth-form .hint { color: var(--text-muted); font-size: 0.9em; margin-block-start: var(--space-2); }
.signout-form, form.inline { display: inline-block; margin: 0; }
.remember { display: flex; align-items: center; gap: var(--space-2); margin-block-end: var(--space-4); }
.btn-secondary {
  background: transparent; color: var(--text-default);
  border: 1px solid var(--border-subtle);
}
.hero .btn-secondary { color: var(--color-white); border-color: var(--color-white); }

/* Theme toggle (TA-1): a compact icon control, not a CTA. Class specificity
   overrides the generic `.btn, button` rule above. Icon color follows
   currentColor (the SVG strokes reference currentColor) so it stays legible
   in both themes; hover/focus reuse existing semantic tokens only. */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-default);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm);
  padding: var(--space-1);
}
.theme-toggle:hover { background: var(--border-subtle); filter: none; text-decoration: none; }

/* Forms */
label { display: block; font-weight: var(--fw-semibold); margin-block-end: var(--space-1); }
/* background/border themed (TA-3 live-fix): --color-white/--color-border are
   fixed Layer-1 primitives, so in dark theme (--text-default = white) a field
   left on fixed white text is illegible. --surface-page is white in light
   (unchanged look) and dark navy in dark, sitting below the --surface-raised
   card the field lives in — a correctly recessed field, never white-on-white.
   --border-subtle is the themed equivalent of --color-border (visible cream
   in light, translucent white in dark; the fixed border is invisible on dark
   navy). color: var(--text-default) was already correct. */
input[type='text'], input[type='email'], input[type='password'], input[type='number'], textarea, select {
  width: 100%; max-width: 28rem;
  font-family: var(--font-stack); font-size: var(--fs-body);
  color: var(--text-default); background: var(--surface-page);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
}
/* Radio/checkbox controls (intake.eta's fieldset groups): accent-color is a
   control, the same documented fixed-value exception tokens.css calls out for
   .btn's background — --color-accent is intentionally the same brand blue in
   both themes rather than a surface/text semantic that must adapt, and it
   clears the 3:1 non-text contrast minimum against the dark page surface
   (measured ~4.08:1 — see task report). Prevents the native controls from
   sitting at browser-default blue on dark. */
input[type='radio'], input[type='checkbox'] { accent-color: var(--color-accent); }
.field { margin-block-end: var(--space-4); }
/* Phase 1.5 mobile pass (measured at 360px): the DNS records table is wider
   than a phone. Its wrapper scrolls on its own axis so the page never scrolls
   sideways; the rule lived only in the markup until now. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.table-scroll table { min-width: 100%; }
/* On a phone a five-column DNS table is unreadable even when it scrolls, so
   each record becomes a block with its cells labelled, the way registrars
   present records on mobile. data-label carries the column heading. */
@media (max-width: 40rem) {
  .dns-records thead { display: none; }
  .dns-records, .dns-records tbody, .dns-records tr, .dns-records td { display: block; width: 100%; }
  .dns-records tr { padding: var(--space-3) 0; border-block-end: 1px solid var(--border-subtle); }
  .dns-records td { padding: var(--space-1) 0; border: 0; overflow-wrap: anywhere; }
  .dns-records td[data-label]:not([data-label=""])::before {
    content: attr(data-label); display: block; direction: rtl; text-align: start;
    font-size: var(--fs-small, 0.85rem); color: var(--text-muted);
  }
  .dns-records td.actions { display: flex; gap: var(--space-3); }
}
.error { color: var(--danger); font-weight: var(--fw-semibold); }

/* Phase 1.5 baseline: a form says what went wrong NEXT TO the field that is
   wrong, not only as a banner at the top. Rendered by views/field-errors.ts,
   which also sets aria-invalid on the input and points aria-describedby here,
   so a screen reader reaches the message from the field itself. Reuses the
   same functional --danger as .error rather than introducing a second red. */
.field-error {
  color: var(--danger);
  font-weight: var(--fw-semibold);
  font-size: 0.875rem;
  margin: 0.35rem 0 0;
}
/* The field itself carries the state too, so the connection is visible and not
   only announced. Colour is never the sole signal: the message sits beside it. */
[aria-invalid="true"] { border-color: var(--danger); }

/* Certificate state on the project (Phase 1.5 Tier 1 item 4). Three tones, and
   'pending' is deliberately not a warning colour: a site still coming up, or a
   domain still waiting on its delegation, is the ordinary case on the day
   someone buys. Reuses the existing functional hues, no new palette. */
.cert-status { font-size: 0.9375rem; margin: 0.35rem 0 0; }
.cert-ok { color: var(--signal-live); }
.cert-pending { color: var(--text-muted); }
.cert-bad { color: var(--danger); font-weight: var(--fw-semibold); }
/* Themed raised surface + explicit text color (TA-3 live-fix): the previous
   fixed-cream --surface-warm + --color-border pair set no explicit text
   color, so in dark theme it inherited --text-default's white onto a fixed
   cream background — white-on-cream, illegible. --surface-raised/
   --text-default is the same pairing the .card rule already uses safely in
   both themes. */
.notice {
  background: var(--surface-raised); border: 1px solid var(--border-subtle);
  color: var(--text-default);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
}

/* Pricing / money surfaces */
/* Instrument-panel emphasis (TA-4): the total is the focal figure, so it gets
   a themed divider above it plus tabular numerals so the digits line up.
   --border-subtle (not the fixed-cream --color-border primitive) so the
   divider stays visible on dark navy — the earlier hardcode vanished there. */
.totals { font-weight: var(--fw-bold); border-block-start: 1px solid var(--border-subtle); padding-block-start: var(--space-2); font-variant-numeric: tabular-nums; }
.price { font-size: var(--fs-h3card); font-weight: var(--fw-bold); }
/* Landing-only instrument touch (second class, base .price rule shared with
   money/checkout surfaces is untouched): tabular numerals for the ₪ figure. */
.price-figure { font-variant-numeric: tabular-nums; }
/* Consent legibility fix (TA-4, legal-safety): the §28 auto-renewal/
   variable-price disclosure was on --text-muted (~2.54:1 on the light card —
   fails AA 4.5:1). Moved to --text-default (19.80:1 light / 16.35:1 dark on
   --surface-raised — see task report for full before/after numbers). Stays
   visually secondary via the smaller --fs-eyebrow size, not via a washed-out
   color. Only this color property changes; the consentLine() copy module
   (not this file) owns the string, so the byte-freeze tests are untouched. */
.consent { font-size: var(--fs-eyebrow); color: var(--text-default); max-width: 60ch; }
.cadence { display: flex; gap: var(--space-4); flex-wrap: wrap; }
/* Selectable-row treatment: each cadence choice reads as its own panel,
   themed border only (no fill/motion change). */
.cadence-option { flex: 1 1 14rem; border: 1px solid var(--border-subtle); border-radius: var(--radius-sm); padding: var(--space-3); }
/* .cadence / .cadence-option are still the checkout's (service-detail.eta)
   cadence panels. The plan step's own location picker, .badge-recommended and
   .cadence-savings were removed with the rev-2 redesign: the plan step no
   longer has a location picker or a recommended badge, and its saving now
   rides the segmented control's .save-badge below. */
.cadence { border: 0; padding: 0; margin: var(--space-4) 0; }
.cadence legend { padding: 0; margin-block-end: var(--space-2); font-weight: var(--fw-bold); }

/* Bill statement list (TA-4): was an unstyled <ul> — bullet reset + a themed
   hairline between line items so a multi-line bill reads as a statement in
   both themes, matching the .price-lines treatment used on the checkout. */
.bill-lines { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.bill-lines li { border-block-end: 1px solid var(--border-subtle); padding-block-end: var(--space-2); }
.bill-lines li:last-child { border-block-end: 0; padding-block-end: 0; }

/* ==========================================================================
   Payment history (Phase 1.5 item 2)
   Each row is one payment that actually happened. Laid out as a list rather
   than a table: on a phone a four-column money table either scrolls sideways
   or collapses into something unreadable, and there is no cross-row
   comparison here that a table would buy. The amount and the reference sit
   together on their own line so the eye finds "how much" and "which invoice"
   in one place, which is what someone reconciling their books is after.
   ========================================================================== */
.section-lead { color: var(--text-muted); margin: 0 0 var(--space-4); }
.empty-state { color: var(--text-muted); margin: 0; }
.payment-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-4); }
.payment-row { border-block-end: 1px solid var(--border-subtle); padding-block-end: var(--space-4); }
.payment-row:last-child { border-block-end: 0; padding-block-end: 0; }
.payment-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-4); justify-content: space-between; }
.payment-desc { flex: 1 1 12rem; font-weight: var(--fw-semibold); }
.payment-date { color: var(--text-muted); font-size: var(--fs-eyebrow); font-variant-numeric: tabular-nums; }
.payment-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-4); margin-block-start: var(--space-1); }
/* Fix-wave finding 6: this list carries no rule at all before this, so it
   rendered with the browser default bullets and left padding — inconsistent
   with the rest of the payment row, which is styled bullet-free throughout.
   Same muted, small-eyebrow treatment as .payment-meta beside it; the label:
   amount layout (bdi around the figure only) reads fine unchanged in RTL. */
.payment-lines { list-style: none; margin: var(--space-1) 0 0; padding: 0; color: var(--text-muted); font-size: var(--fs-eyebrow); }
.payment-lines li { padding: 0.1rem 0; }
/* Tabular figures so amounts line up down the column even at different widths. */
.payment-amount { font-variant-numeric: tabular-nums; font-weight: var(--fw-semibold); }
.payment-ref { color: var(--text-muted); font-size: var(--fs-eyebrow); }
.payment-refund { color: var(--text-muted); font-size: var(--fs-eyebrow); margin: var(--space-1) 0 0; }
.payment-pending { color: var(--text-muted); font-size: var(--fs-eyebrow); margin: var(--space-2) 0 0; }
.payment-invoice { display: inline-block; margin-block-start: var(--space-2); font-size: 15px; }

/* One back link, so inner pages stop each inventing their own. */
.back-link { display: inline-block; margin-block-start: var(--space-2); }

/* ==========================================================================
   Status page (Phase 1.5 item 5)
   Colour is a reinforcement here, never the message: the state is carried by
   the sentence itself, so the page still reads correctly in monochrome, to a
   screen reader, and to someone who cannot separate red from green.
   ========================================================================== */
.status-line { font-size: 20px; margin: 0 0 var(--space-2); }
.status-ok { color: var(--text-default); }
.status-bad { color: var(--danger); }
.status-checked { color: var(--text-muted); font-size: var(--fs-eyebrow); margin: 0 0 var(--space-6); font-variant-numeric: tabular-nums; }

/* Dashboard "big blocks" (founder-ordered restyle, built 2026-08-31): a
   grid of project cards in place of hairline rows inside one tall card.
   Card chrome mirrors the .card rule's tokens exactly. .status stays a
   plain themed pill — H1 (BINDING): it renders whatever real statusLabel
   the data provides, never a fabricated "LIVE"/uptime figure, so it
   deliberately does NOT use --signal-live; --text-default clears AA in
   both themes (--text-muted fails ~2.54:1 on the light surface — same
   issue TA-4 fixed on .consent), which is why the label text and the
   .region metadata both use --text-default rather than the muted token. */
.page-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--space-3); margin-block-end: var(--space-4);
}
.page-head h1 { margin: 0; }
ul.service-list {
  list-style: none; margin: var(--space-4) 0 0; padding: 0;
  display: grid; gap: var(--space-4);
  grid-template-columns: repeat(auto-fill, minmax(min(20rem, 100%), 1fr));
}
ul.service-list li.project-card {
  display: flex; flex-direction: column; gap: var(--space-3);
  background: var(--surface-raised); border: 1px solid var(--color-border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-card);
  padding: var(--space-5);
}
.project-card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-3); flex-wrap: wrap;
}
.project-name { font-size: var(--fs-h3card); font-weight: var(--fw-semibold); }
.project-card .live-url { margin: 0; }
.project-card .domain-list, .domains-owned .domain-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-1);
  font-size: var(--fs-eyebrow);
}
.project-card-link { margin: 0; font-size: var(--fs-eyebrow); }
.project-card-meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-3);
  margin-block-start: auto; padding-block-start: var(--space-3);
  border-block-start: 1px solid var(--border-subtle);
}
.project-card-meta .delete-project { margin-inline-start: auto; }
/* The bare .region rule elsewhere is a bordered block (the location section
   of other screens); inside the card's meta row it is a plain inline label,
   and the shared .price rule's h3card weight would out-shout the project
   name, so both are scoped back down here. */
.project-card-meta .region { border-block: 0; margin: 0; padding: 0; max-width: none; }
.project-card-meta .price { font-size: var(--fs-body); font-weight: var(--fw-semibold); }
.status, .region, .renewal { color: var(--text-default); font-size: var(--fs-eyebrow); }
.status {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
}

/* Provisioning "ready" cut-zone moment (R5 First Light): the one celebratory
   state (server genuinely running). Calm success treatment — a quiet accent
   rule + semibold weight, no signal-green fill/text. The ready moment now
   carries the gold north star (.status-star), the constellation's "live /
   וזה באוויר" destination, in place of the old green live-dot: same "you're
   live" signal in the brand's own vocabulary. The star twinkles via
   ready-star and holds still under prefers-reduced-motion (brief §7). */
.status-ready {
  display: flex; align-items: center; gap: var(--space-2);
  font-weight: var(--fw-semibold);
  border-inline-start: 4px solid var(--border-subtle);
  padding-inline-start: var(--space-3);
}
.status-star {
  display: inline-flex; line-height: 0; flex-shrink: 0;
  animation: ready-star 2.4s ease-in-out infinite;
}
@keyframes ready-star {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .72; transform: scale(1.1); }
}

/* Destructive action (TA-4): service-detail.eta's "Turn off renewal" button
   had no rule and rendered as the primary brand-accent CTA. Outline/secondary
   treatment (not a solid fill) so it reads as caution, not the default action;
   --danger text/border clears AA in both themes (~7.33:1 light / ~5.95:1 dark
   against --surface-raised — see task report). No new hover/motion: the
   shared `button:hover { filter: brightness(0.92) }` rule already covers it. */
.btn.danger, button.danger {
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--danger);
}

/* Tables (dashboard/bill) — themed divider (TA-4): same fixed-cream-vanishes-
   on-dark-navy hardcode as .totals above, fixed the same way. */
table { border-collapse: collapse; width: 100%; }
th, td { text-align: start; padding: var(--space-2) var(--space-3); border-block-end: 1px solid var(--border-subtle); }
th { font-weight: var(--fw-semibold); color: var(--text-muted); font-size: var(--fs-eyebrow); }

/* RTL */
[dir='rtl'] main.page, [dir='rtl'] .site-header-inner { direction: rtl; }
[dir='rtl'] { text-align: right; }

@media (max-width: 40rem) {
  h1 { font-size: var(--fs-h3); }
  .hero { padding: var(--space-6) var(--space-4); }
}

/* Motion budget (BINDING): every motion on the site must render its static
   end-state under prefers-reduced-motion. The First Light hero/constellation
   motion (twinkle, north-star beacon, dawn breathe, CTA glow, on-load rise)
   lands in later restyle phases and each is neutralized here as it ships. */
@media (prefers-reduced-motion: reduce) {
  .live-dot,
  .status-star {
    animation: none;
    opacity: 1;
  }
  /* First Light hero + constellation motion holds still (brief §7). */
  .sky-stars .tw,
  .sky-dawn,
  .sky-northstar,
  .northstar-glow,
  .sky-scene .btn-sun,
  .node,
  .const-arc {
    animation: none;
  }
  /* node-rise/const-draw are on-load; with animation removed the nodes revert
     to visible (opacity 1) and the arc to its resting faint state. */
  .const-arc { opacity: .5; }
}

/* Analytics P2 — opt-in consent banner (First Light, tokens only, RTL-safe via
   logical properties). A fixed bottom bar; equal-weight accept/reject (no dark
   pattern — both are full buttons, same size/typography, only the colour role
   differs). Never rendered on payment-entry pages (analyticsId suppressed).
   All colour pairs reuse locked AA-safe tokens: accept = white on --color-accent
   (R6.1, 4.68:1); reject/text = --text-default on --surface-* (9-17:1). */
.consent-banner {
  position: fixed; inset-inline: 0; inset-block-end: 0; z-index: 50;
  background: var(--surface-raised); color: var(--text-default);
  border-block-start: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-card);
  padding: var(--space-4);
}
.consent-banner[hidden] { display: none; }
.consent-banner-inner {
  max-width: 60rem; margin-inline: auto;
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-4);
}
.consent-banner-copy { flex: 1 1 20rem; display: flex; flex-direction: column; gap: var(--space-1); }
.consent-banner-title { margin: 0; font-weight: var(--fw-semibold); font-size: var(--fs-body); }
.consent-banner-text {
  margin: 0;
  font-size: var(--fs-eyebrow); line-height: var(--lh-normal);
}
.consent-banner-actions { display: flex; gap: var(--space-3); flex-shrink: 0; }
.consent-banner-actions .btn { font-size: var(--fs-eyebrow); }
/* Reject is equal weight to accept: a full, clearly-legible button on the
   page surface with a visible border — not a faint ghost. */
.consent-reject {
  background: var(--surface-page); color: var(--text-default);
  border: 1px solid var(--border-subtle);
}
.consent-reject:hover { filter: brightness(0.96); }
/* Footer "privacy settings" reopen control — a link-styled button matching the
   footer links (overrides the generic .btn/button accent fill by specificity). */
.privacy-settings-link {
  background: none; border: 0; padding: 0; cursor: pointer;
  color: var(--text-default); font: inherit; font-size: var(--fs-eyebrow);
}
.privacy-settings-link:hover { color: var(--link); text-decoration: underline; }

/* Launch screen — live deploy-stage checklist (Task 8). States mirror the
   .status-chip-live / --signal-live convention already used for LIVE status;
   failed reuses --danger (the same functional red as .error). */
.launch-checklist {
  list-style: none; margin: 0 0 var(--space-4); padding: 0;
  display: flex; flex-direction: column; gap: var(--space-2);
}
.launch-check {
  display: flex; align-items: center; gap: var(--space-2);
  font-size: var(--fs-body); color: var(--text-default);
}
.launch-check-icon { inline-size: 1.25em; text-align: center; flex-shrink: 0; }
.launch-check.is-pending { color: var(--text-default); opacity: 0.5; }
.launch-check.is-active { color: var(--text-default); font-weight: var(--fw-semibold); }
.launch-check.is-active .launch-check-icon { animation: launch-check-spin 1.4s linear infinite; }
.launch-estimate { margin-block: var(--space-2) 0; color: var(--text-muted); }
.launch-estimate.is-longer { color: var(--text-default); font-weight: var(--fw-semibold); }
.launch-check.is-done { color: var(--signal-live); }
.launch-check.is-failed { color: var(--danger); font-weight: var(--fw-semibold); }
@keyframes launch-check-spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .launch-check.is-active .launch-check-icon { animation: none; }
}

/* Google sign-in button (3.G): the standard multicolor G, inline SVG (strict
   CSP, no external assets), on a white tile beside the label per Google's
   brand rules (the G's own colors need a neutral ground on the accent-blue
   button). The SVG paths are the well-known four-color G. */
.btn-google { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); }
.btn-google .g-mark {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 50%; background: #fff; flex: none;
}

/* Signup/signin form polish (3.F, conservative): the fields were capped at
   28rem and hugged the inline-start edge of a 60rem card, and their subtle
   border read as anemic against the page background. The form becomes a
   centered column and its inputs fill it, with a clearly visible border
   (--text-muted clears the 3:1 non-text minimum in both themes) and roomier
   padding. Layout + contrast only — no redesign. */
.auth-form { max-width: 34rem; margin-inline: auto; width: 100%; }
.auth-form input[type='email'], .auth-form input[type='password'], .auth-form input[type='text'] {
  max-width: none;
  padding: var(--space-3);
  border-color: var(--text-muted);
}
.auth-form input:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 1px; }
.auth-form .btn[type='submit'], .auth-form button[type='submit'] { width: 100%; }
/* The sibling Google button block centers under the same column. */
.oauth-alt { max-width: 34rem; margin-inline: auto; margin-block-start: var(--space-4); text-align: center; }

/* ==========================================================================
   Site nav (founder ruling 2026-08-22)
   Two fixed links plus one session-dependent slot. No dropdown, no drawer,
   no header logout (/signout is POST-only + CSRF; logout lives on /dashboard).
   The theme toggle is demoted from the loudest element in the header to a
   quiet one — it is a preference control, not a destination.
   ========================================================================== */
.site-nav { display: flex; align-items: center; gap: var(--space-4); margin-inline-start: var(--space-4); }
.site-nav a { color: var(--text-muted); text-decoration: none; font-size: 15px; padding: var(--space-1) 0; border-block-end: 2px solid transparent; }
.site-nav a:hover, .site-nav a:focus-visible { color: var(--text-default); border-block-end-color: var(--color-accent); text-decoration: none; }
.site-header-end { margin-inline-start: auto; display: flex; align-items: center; gap: var(--space-3); }
.nav-session {
  color: var(--text-default); text-decoration: none; font-size: 15px; font-weight: var(--fw-semibold);
  padding: var(--space-2) var(--space-4); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill); background: var(--surface-raised);
}
.nav-session:hover, .nav-session:focus-visible { border-color: var(--color-accent); color: var(--color-accent); text-decoration: none; }

/* ==========================================================================
   Account menu (Phase 1.5 item 1)
   The signed-in session slot is a <details> rather than a scripted dropdown:
   the summary is focusable, opens on Enter/Space, and is announced as
   expanded/collapsed with no JS, so it survives a script failure and a
   keyboard-only visit. It doubles as the mobile menu, which is why the panel
   is absolutely positioned instead of pushing the header to a second row.
   Positioned with logical properties (inset-inline-end) so it hangs off the
   correct edge under dir="rtl", which every customer-facing page uses.
   ========================================================================== */
.account-menu { position: relative; }
.account-menu-trigger {
  display: flex; align-items: center; gap: var(--space-2);
  color: var(--text-default); font-size: 15px; font-weight: var(--fw-semibold);
  padding: var(--space-2) var(--space-4); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill); background: var(--surface-raised);
  cursor: pointer; list-style: none; -webkit-user-select: none; user-select: none;
}
/* Both spellings: the default disclosure triangle would sit next to the email. */
.account-menu-trigger::-webkit-details-marker { display: none; }
.account-menu-trigger::marker { content: ''; }
.account-menu-trigger:hover, .account-menu-trigger:focus-visible { border-color: var(--color-accent); color: var(--color-accent); }
/* An email is LTR text inside an RTL header: without the override the
   punctuation reorders and reads wrong. Long addresses ellipsize rather than
   pushing the theme toggle off the row. */
.account-menu-label { max-width: 18ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: ltr; }
.account-menu-caret { flex: none; transition: transform 120ms ease; }
.account-menu[open] .account-menu-caret { transform: rotate(180deg); }
.account-menu-panel {
  position: absolute; inset-block-start: calc(100% + var(--space-2)); inset-inline-end: 0;
  z-index: 20; min-width: 15rem; display: flex; flex-direction: column;
  background: var(--surface-raised); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md); box-shadow: var(--shadow-card); padding: var(--space-2);
}
.account-menu-panel a {
  color: var(--text-default); text-decoration: none; font-size: 15px;
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
}
.account-menu-panel a:hover, .account-menu-panel a:focus-visible { background: var(--surface-page); color: var(--color-accent); text-decoration: none; }
.account-menu-panel a[aria-current='page'] { color: var(--color-accent); font-weight: var(--fw-semibold); }
/* Sign out is separated by a rule: it is the one item that ends the session,
   and it should not read as a fourth destination. */
.account-menu-signout { display: block; margin: var(--space-2) 0 0; padding-block-start: var(--space-2); border-block-start: 1px solid var(--border-subtle); }
.account-menu-signout .btn-quiet { width: 100%; }
@media (prefers-reduced-motion: reduce) {
  .account-menu-caret { transition: none; }
}

/* ==========================================================================
   Plan step — price card (Design rev 2, founder notes 2026-08-22)
   Hostinger's transferable move: the price is not loose text on the page, it
   is ONE raised object holding the period control, the figure and the CTA, so
   the eye lands on the number and the next action without a scan.
   Deliberately NOT taken from that reference: struck-through anchor prices,
   "% OFF" against a list price we never charged, and countdown urgency —
   each needs a fake original price, which the §1 honesty guardrail bars.
   ========================================================================== */
.plan-project { color: var(--text-muted); margin: 0 0 var(--space-6); }
.plan-project strong { color: var(--text-default); font-weight: var(--fw-semibold); }

/* Segmented billing-period control. These are RADIOS under the styling, not
   buttons: a browser without JS must keep the cadence choice, and a <button>
   would have needed JS to set a hidden field. The native input is hidden from
   sight but still focusable, so keyboard and screen-reader users get the
   normal radio-group behaviour. */
/* The track carries a visible border so the UNSELECTED options read as
   choices too — on the dark theme the page/raised surfaces are close
   enough that the selected chip alone left its siblings looking like
   plain text (founder pass 2026-08-31). Options wrap as whole pills;
   the label span never breaks mid-token ("2GB · 1 vCPU ·" / "50GB"). */
.segment { display: flex; flex-wrap: wrap; gap: var(--space-1); border: 1px solid var(--border-subtle); padding: var(--space-1); margin: 0 0 var(--space-6); background: var(--surface-page); border-radius: var(--radius-pill); }
.segment-option span { white-space: nowrap; }
.segment-option {
  /* position: relative anchors the absolutely-positioned 1px radio inside the
     label. Without it the input escapes to the nearest positioned ancestor. */
  position: relative;
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill); padding: 10px var(--space-3);
  font-weight: var(--fw-semibold); color: var(--text-default); cursor: pointer; text-align: center;
}
.segment-option input { position: absolute; opacity: 0; width: 1px; height: 1px; }
/* --shadow-card, not a bespoke rgba: this file's rule is that a color which
   is not a token does not belong here. */
.segment-option:has(input:checked) { background: var(--surface-raised); color: var(--text-default); box-shadow: var(--shadow-card); }
.segment-option:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.save-badge {
  display: inline-block; background: var(--signal-live); color: var(--color-navy);
  border-radius: var(--radius-pill); padding: 0 var(--space-2);
  font-size: 12px; font-weight: var(--fw-bold); margin-inline-start: var(--space-1); white-space: nowrap;
}

.price-hero { display: flex; align-items: baseline; gap: var(--space-3); flex-wrap: wrap; margin: 0 0 var(--space-1); }
.price-figure { font-size: 52px; font-weight: var(--fw-bold); letter-spacing: -.025em; line-height: 1; }
.price-per { font-size: 20px; font-weight: var(--fw-semibold); }
.price-vat { color: var(--text-muted); font-size: var(--fs-eyebrow); margin: 0 0 var(--space-6); }
.btn-pay { display: block; width: 100%; text-align: center; font-size: 17px; }

/* Itemization as a table, not one long sentence. This is the §12
   pass-through honesty artifact so it stays visible — it just stops being the
   loudest thing on the page. Numerals sit in a tabular mono column; the ₪ is
   bdi-isolated in the markup so it stays left of its digits inside the RTL run. */
.breakdown { width: 100%; max-width: 36rem; border-collapse: collapse; margin: 0 0 var(--space-6); font-size: var(--fs-eyebrow); }
.breakdown caption { text-align: start; color: var(--text-muted); padding-block-end: var(--space-2); }
.breakdown th { text-align: start; font-weight: var(--fw-regular); color: var(--text-muted); padding: var(--space-2) 0; border-block-end: 1px solid var(--border-subtle); }
.breakdown td { text-align: end; padding: var(--space-2) 0; border-block-end: 1px solid var(--border-subtle); font-family: var(--font-mono); font-variant-numeric: tabular-nums; white-space: nowrap; width: 7.5em; }
.breakdown tfoot th, .breakdown tfoot td { border-block-end: 0; border-block-start: 2px solid var(--text-default); font-weight: var(--fw-bold); color: var(--text-default); padding-block-start: var(--space-3); }

/* Region: dashboard.eta's per-service region tag (a plain inline span, not a
   picker) — the disclosure/alternates markup this block once styled was
   deleted with the recommendation page (basket-cleanup L5). */
.region { max-width: 36rem; margin: 0 0 var(--space-6); border-block: 1px solid var(--border-subtle); padding: var(--space-3) 0; }

.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

@media (max-width: 520px) {
  /* Measured in a browser at 375px: the full lockup, two nav links, the
     session pill and the toggle needed 388px of a 343px content box. The
     lockup shrinks and the pill drops to a plain bold link so the header
     stays one row instead of wrapping to two. */
  .site-header-inner { gap: var(--space-2); }
  .brand-lockup svg { width: 110px; height: 15px; }
  .site-nav { gap: var(--space-3); margin-inline-start: var(--space-2); }
  .site-nav a { font-size: 13px; }
  .nav-session { padding: 0; font-size: 13px; border: 0; background: none; border-radius: 0; }
  /* Same reasoning as .nav-session above: at 375px the bordered pill plus a
     full email pushed the header to two rows. Strip the pill and cap the
     label hard; the menu itself is unchanged. */
  .account-menu-trigger { padding: 0; font-size: 13px; border: 0; background: none; border-radius: 0; }
  .account-menu-label { max-width: 10ch; }
  .account-menu-panel { min-width: 13rem; }
  .price-figure { font-size: 42px; }
  .segment-option { padding: 9px var(--space-2); font-size: 14px; }
}

/* The shell's header was brand + toggle only, so `justify-content:
   space-between` was enough. With a nav between them the end-group is pushed
   by `margin-inline-start: auto` instead, and space-between would fight it.
   The desktop `gap` lives on the base .site-header-inner rule higher up, NOT
   here: this block sits after the max-width media query, so an equal-specificity
   gap here would win over the mobile one and the header would stay two rows. */
.site-header-inner { justify-content: flex-start; flex-wrap: wrap; }

/* Item 11: the devices list on the account page. */
.sessions { list-style: none; padding: 0; margin: 0 0 1rem; }
.session { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 1rem; padding: 0.6rem 0; border-bottom: 1px solid var(--border-subtle, #e5e5e5); }
.session-device { flex: 1 1 12rem; }
.session-meta { font-size: 0.85rem; color: var(--text-muted); }
.inline-form { display: inline; margin: 0; }
.activity { list-style: none; padding: 0; margin: 0 0 1rem; }
.activity li { padding: 0.35rem 0; border-bottom: 1px solid var(--border-subtle, #e5e5e5); }
.activity-at { font-size: 0.85rem; color: var(--text-muted); margin-inline-end: 0.5rem; }
.requests { list-style: none; padding: 0; margin: 0 0 1rem; }
.requests li { padding: 0.35rem 0; border-bottom: 1px solid var(--border-subtle, #e5e5e5); }
.request-state { font-size: 0.85rem; color: var(--text-muted); margin-inline-start: 0.5rem; }
.request-state.open { color: inherit; font-weight: 600; }

/* Item 22: two-factor setup and recovery codes. */
.qr svg { width: 200px; height: 200px; display: block; margin: 0.5rem 0; background: #fff; padding: 0.25rem; border-radius: 6px; }
.manual-key { font-size: 1.05rem; letter-spacing: 0.08em; word-break: break-all; }
.recovery-codes { columns: 2; list-style: none; padding: 0; margin: 0.75rem 0; }
.recovery-codes li { margin: 0.2rem 0; }
.recovery-codes code { font-size: 1.05rem; }

/* Item 19: resource usage meter. */
.usage h2 { font-size: 1.05rem; margin: 1rem 0 0.25rem; }
.meter { height: 8px; background: var(--surface-2, #e5e7eb); border-radius: 4px; overflow: hidden; margin: 0.25rem 0 0.5rem; }
.meter span { display: block; height: 100%; background: var(--accent, #2563eb); }

/* The cart (/basket, spec 2026-08-30). The line list is the honesty artifact
   the plan step gave up when it collapsed to one number: every charge the
   customer is about to make is its own row with its own cadence word. The
   footer is sticky because the total has to stay visible while the lines
   above it change. */
.basket-controls { display: grid; gap: var(--space-3); max-width: 36rem; }
.basket-controls .segment { margin: 0; }
.basket-controls legend { color: var(--text-default); font-size: var(--fs-body); font-weight: var(--fw-semibold); padding-inline: var(--space-2); margin-block-end: var(--space-1); }
.basket-lines { display: grid; gap: var(--space-2); margin-block: var(--space-4); max-width: 36rem; }
.basket-line { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); padding: var(--space-2) 0; border-block-end: 1px solid var(--border-subtle); }
.line-label { flex: 1 1 auto; }
/* Only the figure itself is unbreakable; the cadence word and the founding
   caption may wrap, or at 360px the caption forces the page sideways. */
.line-price { font-variant-numeric: tabular-nums; }
.line-price > bdi { white-space: nowrap; }
.line-equivalent, .line-founding { color: var(--text-muted); font-size: var(--fs-eyebrow); }
.basket-domain-add { flex-wrap: wrap; }
.basket-domain-add label { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2); flex: 1 1 14rem; }
.basket-domain-add .hint, .basket-domain-add .error { flex: 1 1 100%; margin: var(--space-2) 0 0; }
.basket-domain-remove { margin: 0; }
.basket-footer { position: sticky; bottom: 0; background: var(--surface-raised); padding: var(--space-3); box-shadow: var(--shadow-card); border-radius: var(--radius-md); max-width: 36rem; }
.basket-footer .price-vat, .basket-footer .price-note { margin: 0 0 var(--space-2); }
.price-savings { color: var(--text-muted); font-size: var(--fs-eyebrow); margin: 0 0 var(--space-3); }
.basket-pay .consent { color: var(--text-muted); font-size: var(--fs-eyebrow); max-width: 36rem; margin-block-start: var(--space-3); }

@media (max-width: 480px) {
  /* At 360px the label and the price stopped fitting on one row and the
     price wrapped under a half-empty label; stack them instead. */
  .basket-line { flex-direction: column; align-items: stretch; gap: var(--space-1); }
  .basket-controls .segment { flex-wrap: wrap; }
}

/* Account tabs (plan 2026-08-31, task 1): plain links, zero client JS. */
.account-tabs { display: flex; gap: var(--space-1); margin: 0 0 var(--space-4); border-bottom: 1px solid var(--border-subtle); flex-wrap: wrap; }
.account-tab { padding: var(--space-2) var(--space-4); border-radius: var(--radius-sm) var(--radius-sm) 0 0; text-decoration: none; color: var(--text-muted); }
.account-tab:hover { color: inherit; }
.account-tab-current { color: inherit; font-weight: var(--fw-semibold); border-bottom: 2px solid var(--color-accent); }
@media (max-width: 40rem) { .account-tabs { gap: 0; } .account-tab { padding: var(--space-2) var(--space-3); } }
