/* ============================================================
   Loazi — shared UI polish layer

   HOW THIS WORKS
   Every page keeps its own inline <style> block. This file is
   linked immediately AFTER that block, so at equal specificity
   it wins, and a page can still override anything deliberately
   by using a more specific selector of its own.

   Two rules kept throughout:

     1. NO NEW COLOUR. Every colour here is one of the page's own
        tokens (--teal, --yellow, --text, --border, --surface …)
        or a transparent mix of one. The palette is untouched;
        only its application changes.

     2. :where() FOR DEFAULTS, plain selectors to ENFORCE.
        :where(...) carries zero specificity, so page rules beat
        it — used where a page's intent should win (type sizes).
        Plain selectors are used for the things that should be
        consistent site-wide: radii, elevation, states, motion.

   Dark mode still comes from theme.css, which overrides tokens
   from :root[data-theme="dark"] and :root:not([data-theme="light"]).
   Both out-specify the :root below, so loading later is harmless.
   Everything here reads tokens rather than literals, so it
   themes automatically.
   ============================================================ */

:root {
  /* ── Spacing scale ───────────────────────────────────────────
     One scale, so padding stops being ad hoc. 4px base. */
  --lz-1: 4px;
  --lz-2: 8px;
  --lz-3: 12px;
  --lz-4: 16px;
  --lz-5: 24px;
  --lz-6: 32px;
  --lz-7: 48px;
  --lz-8: 64px;
  --lz-9: 96px;
  --lz-10: 128px;

  /* ── Radii ───────────────────────────────────────────────────
     The site currently mixes 4/6/7/8/9/10/11/12/14/16/18/20/24px.
     These five steps replace that spread. */
  --lz-r-xs: 6px;
  --lz-r-sm: 10px;
  --lz-r-md: 14px;
  --lz-r-lg: 20px;
  --lz-r-xl: 28px;
  --lz-r-pill: 999px;
  --lz-r-btn: 12px;

  /* ── Elevation ───────────────────────────────────────────────
     Teal-tinted and restrained: a hairline doing most of the
     work, with the shadow only suggesting lift. */
  --lz-hairline: rgba(13, 92, 99, 0.10);
  --lz-e0: 0 0 0 1px rgba(13, 92, 99, 0.06);
  --lz-e1: 0 1px 2px rgba(13, 92, 99, 0.04), 0 2px 8px -2px rgba(13, 92, 99, 0.06);
  --lz-e2: 0 1px 2px rgba(13, 92, 99, 0.05), 0 8px 24px -8px rgba(13, 92, 99, 0.12);
  --lz-e3: 0 2px 4px rgba(13, 92, 99, 0.06), 0 18px 48px -16px rgba(13, 92, 99, 0.18);
  --lz-e-press: inset 0 1px 2px rgba(13, 92, 99, 0.14);

  /* ── Motion ──────────────────────────────────────────────────
     One ease for entrances, one for state changes. Nothing
     bounces; nothing runs long enough to be waited on. */
  --lz-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --lz-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --lz-ease-inout: cubic-bezier(0.4, 0, 0.2, 1);
  --lz-t-fast: 140ms;
  --lz-t: 220ms;
  --lz-t-slow: 420ms;

  /* ── Measure and containers ──────────────────────────────── */
  --lz-measure: 68ch;
  --lz-measure-tight: 58ch;
  --lz-container: 1180px;
  --lz-gutter: clamp(20px, 5vw, 48px);

  /* ── Tints of the existing brand colours ──────────────────── */
  --lz-teal-wash: rgba(13, 92, 99, 0.04);
  --lz-teal-tint: rgba(13, 92, 99, 0.08);
  --lz-focus: rgba(13, 92, 99, 0.35);
}

/* Prefer real mixes of the page's own tokens where supported, so
   a page with a different teal (or dark mode) stays coherent. */
@supports (color: color-mix(in srgb, red, blue)) {
  :root {
    --lz-hairline: color-mix(in srgb, var(--teal, #0D5C63) 12%, transparent);
    --lz-teal-wash: color-mix(in srgb, var(--teal, #0D5C63) 4%, transparent);
    --lz-teal-tint: color-mix(in srgb, var(--teal, #0D5C63) 9%, transparent);
    --lz-focus: color-mix(in srgb, var(--teal, #0D5C63) 40%, transparent);
  }
}


/* ============================================================
   1. BASE
   ============================================================ */

/* Smooth in-page jumps, but never fight a reduced-motion setting
   (handled in section 11). */
html { scroll-behavior: smooth; }

/* Anything anchored below a sticky topbar should not land under it. */
:where([id]) { scroll-margin-top: var(--lz-8); }

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

::selection {
  background: var(--lz-teal-tint);
  color: var(--text, #1A1F36);
}

/* A quieter scrollbar. Firefox first, then WebKit. */
@supports (scrollbar-width: thin) {
  :where(html) {
    scrollbar-width: thin;
    scrollbar-color: var(--lz-hairline) transparent;
  }
}
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--lz-hairline);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: var(--lz-r-pill);
}
::-webkit-scrollbar-thumb:hover { background-clip: content-box; background-color: var(--lz-focus); }


/* ============================================================
   2. TYPOGRAPHY
   Sizes stay with the page (:where, so page rules win). What is
   enforced is the optical detail: tracking tightens as type
   grows, leading loosens as it shrinks, and lines stop being
   uncomfortably long.
   ============================================================ */

h1, h2, h3, h4, h5, h6 {
  letter-spacing: -0.021em;
  line-height: 1.12;
  text-wrap: balance;      /* no orphan word on its own last line */
}
h3, h4, h5, h6 {
  letter-spacing: -0.014em;
  line-height: 1.24;
}
h5, h6 { letter-spacing: -0.006em; }

:where(h1) { font-size: clamp(2.1rem, 1.3rem + 3.1vw, 3.6rem); }
:where(h2) { font-size: clamp(1.6rem, 1.1rem + 1.9vw, 2.5rem); }
:where(h3) { font-size: clamp(1.15rem, 1rem + 0.6vw, 1.4rem); }

/* Body copy: comfortable leading, and a measure that keeps lines
   scannable on wide screens. */
:where(p, li) { line-height: 1.7; }
p { text-wrap: pretty; }

/* Prose paragraphs get a measure; paragraphs inside UI chrome
   (cards, tables, banners, form rows) must not be narrowed. */
:where(.hero-sub, .section-sub, .page-sub, .lead, article p, .prose p) {
  max-width: var(--lz-measure);
}

/* Small supporting text, consistently quieter. */
:where(.form-hint, .form-sub, .stat-label, .nav-section-label, .eyebrow, .section-tag, .course-eyebrow, .topbar-date, .user-role) {
  letter-spacing: 0.01em;
  line-height: 1.5;
}

/* Eyebrows and section tags read as labels, not headings. */
.eyebrow, .section-tag, .nav-section-label {
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 600;
  font-size: 0.72rem;
}

/* Numerals in stats and tables align in columns. */
:where(.stat-num, .num, .notification-count, .nav-badge, td, th) {
  font-variant-numeric: tabular-nums;
}

/* Links inside prose underline properly rather than sitting flush
   against the baseline. */
:where(article, .prose) a:not([class]) {
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: opacity var(--lz-t-fast) var(--lz-ease-inout);
}
:where(article, .prose) a:not([class]):hover { opacity: 0.7; }


/* ============================================================
   3. FOCUS
   One visible ring everywhere, keyboard only.
   ============================================================ */

:where(a, button, input, select, textarea, summary, [tabindex], [role="button"]):focus-visible {
  outline: 2px solid var(--teal-ink, var(--teal, #0D5C63));
  outline-offset: 2px;
}
/* Mouse users never see it. */
:where(a, button, [role="button"]):focus:not(:focus-visible) { outline: none; }


/* ============================================================
   4. BUTTONS
   Radius, weight, motion and states unified. Colour is left to
   the page, so a primary button stays whatever teal it was.
   ============================================================ */

.btn,
.btn-primary,
.btn-secondary,
.btn-outline,
.btn-ghost,
.btn-sm,
.btn-back,
.sign-out-btn,
.rail-btn,
.icon-btn,
button.btn,
a.btn {
  transition:
    transform var(--lz-t-fast) var(--lz-ease),
    box-shadow var(--lz-t) var(--lz-ease),
    background-color var(--lz-t) var(--lz-ease-inout),
    border-color var(--lz-t) var(--lz-ease-inout),
    color var(--lz-t) var(--lz-ease-inout),
    opacity var(--lz-t) var(--lz-ease-inout);
  -webkit-tap-highlight-color: transparent;
}

.btn,
.btn-primary,
.btn-outline,
.btn-ghost,
button.btn,
a.btn {
  border-radius: var(--lz-r-btn);
  font-weight: 600;
  letter-spacing: -0.005em;
}

/* Tactile: a small lift on hover, a real press on click. */
.btn:hover,
.btn-primary:hover,
.btn-outline:hover,
.btn-ghost:hover,
button.btn:hover,
a.btn:hover { transform: translateY(-1px); }

.btn:active,
.btn-primary:active,
.btn-outline:active,
.btn-ghost:active,
.btn-sm:active,
.btn-back:active,
.sign-out-btn:active,
.rail-btn:active,
.icon-btn:active,
button.btn:active,
a.btn:active {
  transform: translateY(0) scale(0.985);
  transition-duration: 80ms;
}

/* A disabled or busy button should stop pretending to be tactile. */
.btn[disabled], .btn-primary[disabled], button[disabled],
.btn.is-loading, .btn-primary.is-loading {
  transform: none !important;
  box-shadow: none !important;
  opacity: 0.55;
  cursor: not-allowed;
}

/* Small buttons and icon buttons: square-ish, consistent. */
.btn-sm { border-radius: var(--lz-r-sm); font-weight: 600; }
.icon-btn, .rail-btn, .notification-btn, .hamburger-btn, .theme-toggle-btn {
  border-radius: var(--lz-r-sm);
}
.icon-btn:hover, .rail-btn:hover, .notification-btn:hover, .theme-toggle-btn:hover {
  transform: translateY(-1px);
}

/* Back links read as navigation, not as a button. */
.btn-back { border-radius: var(--lz-r-sm); font-weight: 500; }


/* ============================================================
   5. CARDS AND SURFACES
   Hairline first, shadow second. Backgrounds are left alone —
   several of these sit on teal grounds.
   ============================================================ */

.card,
.stat-card,
.job-card,
.plan-card,
.course-card,
.user-card,
.empty-state,
.alert,
.drawer,
.modal,
.notification-panel {
  border-radius: var(--lz-r-lg);
}

.card,
.stat-card,
.job-card,
.plan-card,
.course-card {
  box-shadow: var(--lz-e1);
  border-color: var(--lz-hairline);
  transition:
    transform var(--lz-t) var(--lz-ease),
    box-shadow var(--lz-t) var(--lz-ease),
    border-color var(--lz-t) var(--lz-ease-inout);
}

/* Hover belongs to cards that actually go somewhere. */
a.card:hover,
a.job-card:hover,
a.course-card:hover,
.card[onclick]:hover,
.job-card[onclick]:hover,
.plan-card:hover,
.stat-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--lz-e2);
  border-color: var(--lz-focus);
}

/* Nothing needs a second border once it has a hairline. */
.card, .stat-card, .job-card, .plan-card, .empty-state {
  border-width: 1px;
}

/* Section separators: one hairline, no double rules. */
.section-divider, hr {
  border: none;
  border-top: 1px solid var(--lz-hairline);
  margin-block: var(--lz-7);
}

/* Chips, badges and pills share one shape. */
.badge, .chip, .company-badge, .course-badge, .nav-badge, .tag, .pill {
  border-radius: var(--lz-r-pill);
  letter-spacing: 0.01em;
  font-weight: 600;
}


/* ============================================================
   6. APP SHELL  (sidebar + topbar, ~20 pages)
   ============================================================ */

/* A lightweight, refined topbar: translucent, hairline instead of
   a shadow, and it stays with you as you scroll. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  border-bottom: 1px solid var(--lz-hairline);
  background: var(--surface, var(--white, #fff));
}
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .topbar {
    background: color-mix(in srgb, var(--surface, #fff) 78%, transparent);
    -webkit-backdrop-filter: saturate(180%) blur(20px);
    backdrop-filter: saturate(180%) blur(20px);
  }
}

.topbar-title {
  letter-spacing: -0.015em;
  line-height: 1.2;
}

/* Sidebar: hairline edge, no shadow, quiet ground. */
.sidebar {
  border-right: 1px solid var(--lz-hairline);
  box-shadow: none;
}

/* Nav items: a soft pill that fills in on hover and commits on
   the active item. */
.nav-item {
  border-radius: var(--lz-r-sm);
  transition:
    background-color var(--lz-t-fast) var(--lz-ease-inout),
    color var(--lz-t-fast) var(--lz-ease-inout),
    transform var(--lz-t-fast) var(--lz-ease);
}
.nav-item:hover {
  background: var(--lz-teal-wash);
  color: var(--teal-ink, var(--teal, #0D5C63));
}
.nav-item.active {
  background: var(--lz-teal-tint);
  color: var(--teal-ink, var(--teal, #0D5C63));
  font-weight: 600;
}
.nav-item .nav-icon { transition: opacity var(--lz-t-fast) var(--lz-ease-inout); opacity: 0.75; }
.nav-item:hover .nav-icon, .nav-item.active .nav-icon { opacity: 1; }

.sidebar-footer, .sidebar-logo { border-color: var(--lz-hairline); }
.user-card { border-radius: var(--lz-r-md); }

/* Content column: generous, and it stops growing before lines get
   unreadable on a 27" display. */
.page-body {
  padding-inline: var(--lz-gutter);
  padding-block: var(--lz-6) var(--lz-9);
}
.page-body > * { max-width: 1400px; }

/* Marketing pages: one consistent content width. */
.nav-links { gap: clamp(18px, 2.4vw, 34px); }
.nav-links a {
  position: relative;
  transition: color var(--lz-t-fast) var(--lz-ease-inout);
}
/* A hairline that grows from the centre on hover — the only
   decoration the nav needs. Filled CTAs sitting in the same list
   (.nav-cta) are buttons, not links, so they are excluded. */
.nav-links a:not(.nav-cta):not(.nav-register)::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: -6px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  opacity: 0;
  transform: scaleX(0.4);
  transition:
    opacity var(--lz-t-fast) var(--lz-ease-inout),
    transform var(--lz-t) var(--lz-ease);
}
.nav-links a:not(.nav-cta):not(.nav-register):hover::after { opacity: 0.35; transform: scaleX(1); }

/* Header CTAs get the same tactility as body buttons. */
.nav-cta, .nav-register, .nav-signin {
  transition:
    transform var(--lz-t-fast) var(--lz-ease),
    box-shadow var(--lz-t) var(--lz-ease),
    background-color var(--lz-t) var(--lz-ease-inout),
    color var(--lz-t) var(--lz-ease-inout),
    opacity var(--lz-t) var(--lz-ease-inout);
}
.nav-cta:hover, .nav-register:hover { transform: translateY(-1px); }
.nav-cta:active, .nav-register:active, .nav-signin:active {
  transform: translateY(0) scale(0.985);
  transition-duration: 80ms;
}

#navbar, .navbar, .site-header {
  border-bottom: 1px solid transparent;
  transition:
    background-color var(--lz-t) var(--lz-ease-inout),
    border-color var(--lz-t) var(--lz-ease-inout),
    box-shadow var(--lz-t) var(--lz-ease-inout);
}


/* ============================================================
   7. FORMS
   ============================================================ */

input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
select,
textarea,
.form-input,
.search-input {
  border-radius: var(--lz-r-sm);
  transition:
    border-color var(--lz-t-fast) var(--lz-ease-inout),
    box-shadow var(--lz-t-fast) var(--lz-ease-inout),
    background-color var(--lz-t-fast) var(--lz-ease-inout);
}

/* One focus treatment: the border commits, a soft ring confirms. */
input:not([type="checkbox"]):not([type="radio"]):focus,
select:focus,
textarea:focus,
.form-input:focus,
.search-input:focus {
  outline: none;
  border-color: var(--teal-ink, var(--teal, #0D5C63));
  box-shadow: 0 0 0 3px var(--lz-teal-tint);
}

::placeholder {
  color: var(--text-muted, #6b7280);
  opacity: 0.75;
}

.form-group { margin-bottom: var(--lz-5); }
.form-row { gap: var(--lz-4); }
:where(label) { letter-spacing: -0.003em; }

/* Checkboxes and radios pick up the brand colour instead of the
   browser default blue. */
input[type="checkbox"], input[type="radio"], input[type="range"], progress {
  accent-color: var(--teal-ink, var(--teal, #0D5C63));
}

/* Invalid only after the field has been touched, never while typing
   the first character. */
input:not(:placeholder-shown):user-invalid,
textarea:not(:placeholder-shown):user-invalid {
  border-color: var(--error, #e53e3e);
}


/* ============================================================
   8. OVERLAYS  (modals, drawers, notification panels)
   ============================================================ */

.modal-overlay, .sidebar-overlay, .notification-panel-overlay, .drawer-overlay {
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: opacity var(--lz-t) var(--lz-ease-inout);
}

.modal, .drawer, .notification-panel {
  border-radius: var(--lz-r-xl);
  box-shadow: var(--lz-e3);
  border: 1px solid var(--lz-hairline);
}
/* Panels that slide in from an edge keep square outer corners. */
.drawer, .notification-panel { border-radius: var(--lz-r-xl) 0 0 var(--lz-r-xl); }

.modal-header, .drawer-header, .notification-panel-header { border-color: var(--lz-hairline); }
.modal-footer, .notification-panel-footer { border-color: var(--lz-hairline); }
.modal-body, .drawer-body { padding-block: var(--lz-5); }

/* Notification rows: quiet until hovered. */
.notification-item, .notification-job {
  transition: background-color var(--lz-t-fast) var(--lz-ease-inout);
}
.notification-item:hover { background: var(--lz-teal-wash); }


/* ============================================================
   9. TABLES
   ============================================================ */

:where(table) { border-collapse: collapse; width: 100%; }

th {
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--text-muted, #6b7280);
}
th, td {
  border-color: var(--lz-hairline);
  padding-block: var(--lz-3);
}
tbody tr { transition: background-color var(--lz-t-fast) var(--lz-ease-inout); }
tbody tr:hover { background: var(--lz-teal-wash); }

/* Tables never force the page sideways on a phone. */
@media (max-width: 768px) {
  :where(.table-wrap, .table-scroll, .table-container) {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}


/* ============================================================
   10. MOTION
   Entrance reveals. js/loazi-ui.js marks only elements that are
   BELOW the fold, so nothing visible on load is ever hidden and
   there is no flash. Without JS, nothing is hidden at all.
   ============================================================ */

.lz-reveal {
  opacity: 0;
  transform: translateY(18px);
  will-change: opacity, transform;
}
.lz-reveal.lz-in {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--lz-t-slow) var(--lz-ease-out),
    transform var(--lz-t-slow) var(--lz-ease-out);
  transition-delay: var(--lz-stagger, 0ms);
}
/* Once it has played, stop holding a compositor layer. */
.lz-reveal.lz-done { will-change: auto; }

/* The loading overlay should dissolve, not disappear. */
.loading-overlay { transition: opacity var(--lz-t) var(--lz-ease-inout); }


/* ============================================================
   11. RESPONSIVE
   Mobile is not a stacked desktop: targets grow, gutters tighten,
   and type steps down before it wraps badly.
   ============================================================ */

@media (max-width: 1024px) {
  .page-body { padding-block: var(--lz-5) var(--lz-8); }
}

@media (max-width: 768px) {
  /* Every interactive thing clears the 44px touch target. */
  .btn, .btn-primary, .btn-secondary, .btn-sm, .btn-back,
  .icon-btn, .rail-btn, .notification-btn, .hamburger-btn,
  .theme-toggle-btn, .nav-item, .sign-out-btn {
    min-height: 44px;
  }
  .icon-btn, .rail-btn, .notification-btn, .hamburger-btn, .theme-toggle-btn {
    min-width: 44px;
  }

  /* Cards get a little less rounded as they get smaller, so the
     radius stays proportional. */
  .card, .stat-card, .job-card, .plan-card, .course-card {
    border-radius: var(--lz-r-md);
  }
  .modal { border-radius: var(--lz-r-lg); }

  .section-divider, hr { margin-block: var(--lz-6); }
  .form-group { margin-bottom: var(--lz-4); }

  /* Long prose should use the full width of a narrow screen. */
  :where(.hero-sub, .section-sub, .page-sub, .lead, article p, .prose p) {
    max-width: none;
  }
}

@media (max-width: 480px) {
  h1, h2 { letter-spacing: -0.015em; }
  .modal { border-radius: var(--lz-r-md); }
  .drawer, .notification-panel { border-radius: var(--lz-r-lg) 0 0 var(--lz-r-lg); }
}

/* Sharpen hairlines on retina, where 1px renders heavier. */
@media (min-resolution: 2dppx) {
  :root { --lz-hairline: rgba(13, 92, 99, 0.09); }
}


/* ============================================================
   12. REDUCED MOTION
   Nothing moves, nothing is hidden waiting to move.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  .lz-reveal, .lz-reveal.lz-in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto;
  }

  .btn:hover, .btn-primary:hover, .btn-outline:hover, .btn-ghost:hover,
  a.btn:hover, button.btn:hover,
  .icon-btn:hover, .rail-btn:hover, .notification-btn:hover,
  .theme-toggle-btn:hover,
  a.card:hover, a.job-card:hover, a.course-card:hover,
  .card[onclick]:hover, .job-card[onclick]:hover,
  .plan-card:hover, .stat-card:hover {
    transform: none;
  }

  .btn:active, .btn-primary:active, .btn-sm:active, .btn-back:active,
  .icon-btn:active, .rail-btn:active, .sign-out-btn:active,
  a.btn:active, button.btn:active {
    transform: none;
  }

  .nav-links a::after { transition: none; }
}


/* ============================================================
   13. MARKETING LAYOUT
   Scoped to pages with no app sidebar, so dashboards are never
   touched. :has() is guarded — where it is unsupported the whole
   block is skipped and pages keep their own layout.

   The container is done with padding rather than a max-width on
   the children: the section still spans the full viewport, so
   full-bleed backgrounds and the hero's Vanta canvas are
   unaffected, while the content lines up on one grid.
   ============================================================ */

@supports selector(:has(*)) {

  body:not(:has(.sidebar)) nav,
  body:not(:has(.sidebar)) section,
  body:not(:has(.sidebar)) footer {
    padding-inline: max(var(--lz-gutter), calc((100% - var(--lz-container)) / 2));
  }

  /* One vertical rhythm for every section. The hero keeps its own
     asymmetric padding, which clears the fixed nav. */
  body:not(:has(.sidebar)) section:not(.hero) {
    padding-block: clamp(4.5rem, 7.5vw, 8rem);
  }

  /* Heading to supporting copy, and copy to the next block. */
  body:not(:has(.sidebar)) .section-title { margin-bottom: var(--lz-3); }
  body:not(:has(.sidebar)) .section-tag { margin-bottom: var(--lz-4); }

  /* A refined header: hairline at rest, and on scroll a whisper of
     elevation instead of a 24px drop shadow. */
  body:not(:has(.sidebar)) nav {
    border-bottom: 1px solid var(--lz-hairline);
  }
  body:not(:has(.sidebar)) nav.scrolled {
    box-shadow: 0 1px 2px rgba(13, 92, 99, 0.04), 0 8px 24px -12px rgba(13, 92, 99, 0.16);
  }
  @supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    body:not(:has(.sidebar)) nav {
      -webkit-backdrop-filter: saturate(180%) blur(20px);
      backdrop-filter: saturate(180%) blur(20px);
    }
  }

  body:not(:has(.sidebar)) footer { padding-block: var(--lz-8) var(--lz-6); }
}

/* Pills in the trust row share the badge shape. */
.logo-pill { border-radius: var(--lz-r-pill); }


/* ============================================================
   14. HERO ENTRANCE
   The headline already reveals itself word by word. The rest of
   the hero follows it in sequence rather than being there all
   along. Above the fold, so it is pure CSS with no observer.
   ============================================================ */

.hero-badge,
.hero-sub,
.hero-actions,
.hero-stats {
  animation: lz-hero-in 0.9s var(--lz-ease-out) both;
}
.hero-badge   { animation-delay: 60ms; }
.hero-sub     { animation-delay: 620ms; }
.hero-actions { animation-delay: 740ms; }
.hero-stats   { animation-delay: 860ms; }

@keyframes lz-hero-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-badge, .hero-sub, .hero-actions, .hero-stats {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* ============================================================
   15. "HOW DID YOU HEAR ABOUT US?" PICKER
   Drawn by js/heard-about.js on register.html and in login.html's
   first-login step. One-tap chips over real radio inputs: the
   input stays in the tab order and the accessibility tree, only
   its dot is hidden.
   ============================================================ */

.ha-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--lz-2);
}
.ha-chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 14px;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  background: var(--white);
  color: var(--text);
  font-size: 0.82rem;
  font-weight: 500;
  letter-spacing: 0;
  margin: 0;
  cursor: pointer;
  user-select: none;
  transition: border-color 0.15s, background-color 0.15s, color 0.15s;
}
/* Both pages colour every `label span` as a required-field asterisk. */
.ha-chip span { color: inherit; margin: 0; }
.ha-chip input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
  margin: 0;
  pointer-events: none;
}
.ha-chip:hover { border-color: var(--teal); }
.ha-chip:has(input:checked) {
  border-color: var(--teal);
  background: var(--teal-pale);
  color: var(--teal);
  font-weight: 600;
}
.ha-chip:has(input:focus-visible) {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}
.ha-other { margin-top: var(--lz-3); }
.ha-other[hidden] { display: none; }
.ha-field.has-error .ha-chip { border-color: var(--error); }
