/* =========================================================================
   HSB Theme System — single source of truth for all public pages
   =========================================================================

   ONE theme system, no per-page duplication. Every public page (landing, login,
   register, recover, verify) links this file and gets identical tokens.

   Theming works off a `data-theme` attribute on <html>, set before first paint
   by the inline bootstrap in hsb-theme.js:

     <html data-theme="light">   explicit light
     <html data-theme="dark">    explicit dark

   The attribute is ALWAYS resolved to a concrete value by the bootstrap — it is
   never absent and never "system". That keeps the CSS to two flat cases instead
   of interleaving prefers-color-scheme media queries, which is what usually
   causes dark mode to look like an inversion rather than a design.

   Structure:
     1. Tokens (light)        2. Tokens (dark)       3. Base / reset
     4. Layout                5. Navigation          6. Buttons
     7. Forms                 8. Cards & surfaces    9. Feedback states
    10. Theme toggle         11. Utilities
   ========================================================================= */

/* ---- 1. Tokens — light ------------------------------------------------- */

:root,
:root[data-theme="light"] {
  /* Brand — carried over from the existing system identity */
  --hsb-brand:            #0891b2;
  --hsb-brand-strong:     #0e7490;
  --hsb-brand-soft:       rgba(8, 145, 178, 0.10);
  --hsb-brand-ring:       rgba(8, 145, 178, 0.22);
  --hsb-accent:           #6366f1;
  /* Separate token for link TEXT. --hsb-brand measures 3.68:1 on white, which
     only passes AA at large sizes, and links here render at ~0.8rem. This
     darker step clears 4.5:1 on both the card and the page background. */
  --hsb-link:             #0e7490;

  /* Surfaces — layered, not flat */
  --hsb-bg:               #f6f9fc;
  --hsb-bg-elev:          #ffffff;
  --hsb-surface:          #ffffff;
  --hsb-surface-2:        #f1f5f9;
  --hsb-surface-glass:    rgba(255, 255, 255, 0.72);

  /* Text */
  --hsb-text:             #0f172a;
  --hsb-text-muted:       #556274;
  /* #7c8ba1 measured 3.46:1 on white — under the 4.5:1 AA floor for small text,
     and this token is used at 0.72rem. Darkened to clear it. */
  --hsb-text-subtle:      #64748b;
  --hsb-text-on-brand:    #ffffff;

  /* Lines & depth */
  --hsb-border:           rgba(15, 23, 42, 0.09);
  --hsb-border-strong:    rgba(15, 23, 42, 0.16);
  --hsb-shadow-sm:        0 1px 2px rgba(15, 23, 42, 0.05);
  --hsb-shadow:           0 1px 3px rgba(15, 23, 42, 0.06), 0 12px 28px -16px rgba(15, 23, 42, 0.22);
  --hsb-shadow-lg:        0 2px 6px rgba(15, 23, 42, 0.06), 0 32px 64px -28px rgba(15, 23, 42, 0.30);

  /* Gradients */
  --hsb-grad-brand:       linear-gradient(135deg, #0891b2 0%, #0e7490 55%, #155e75 100%);
  --hsb-grad-hero:        radial-gradient(60% 60% at 15% 10%, rgba(8, 145, 178, 0.16) 0%, transparent 60%),
                          radial-gradient(50% 50% at 85% 20%, rgba(99, 102, 241, 0.12) 0%, transparent 60%);
  --hsb-grad-text:        linear-gradient(120deg, #0f172a 0%, #0891b2 100%);

  /* Status */
  --hsb-success:          #059669;
  --hsb-success-bg:       rgba(5, 150, 105, 0.10);
  --hsb-warning:          #d97706;
  --hsb-warning-bg:       rgba(217, 119, 6, 0.12);
  --hsb-danger:           #dc2626;
  --hsb-danger-bg:        rgba(220, 38, 38, 0.10);

  color-scheme: light;
}

/* ---- 2. Tokens — dark -------------------------------------------------- */
/* Deliberately designed, not inverted: navy-tinted charcoals (never pure
   black), lifted card surfaces, a brighter brand cyan that survives on dark,
   and softened text instead of pure white. */

:root[data-theme="dark"] {
  --hsb-brand:            #22d3ee;
  --hsb-brand-strong:     #67e8f9;
  --hsb-brand-soft:       rgba(34, 211, 238, 0.12);
  --hsb-brand-ring:       rgba(34, 211, 238, 0.28);
  --hsb-accent:           #818cf8;
  /* On dark the bright cyan already measures 10.37:1 — no separate step needed. */
  --hsb-link:             #22d3ee;

  --hsb-bg:               #0a1220;
  --hsb-bg-elev:          #0f1b2d;
  --hsb-surface:          #111f33;
  --hsb-surface-2:        #16293f;
  --hsb-surface-glass:    rgba(17, 31, 51, 0.72);

  --hsb-text:             #e8f0f8;
  --hsb-text-muted:       #a3b4c8;
  --hsb-text-subtle:      #7f92aa;
  --hsb-text-on-brand:    #04202b;

  --hsb-border:           rgba(148, 175, 205, 0.16);
  --hsb-border-strong:    rgba(148, 175, 205, 0.28);
  --hsb-shadow-sm:        0 1px 2px rgba(2, 8, 20, 0.5);
  --hsb-shadow:           0 1px 3px rgba(2, 8, 20, 0.55), 0 12px 28px -16px rgba(2, 8, 20, 0.8);
  --hsb-shadow-lg:        0 2px 6px rgba(2, 8, 20, 0.6), 0 32px 64px -28px rgba(2, 8, 20, 0.9);

  --hsb-grad-brand:       linear-gradient(135deg, #22d3ee 0%, #0ea5e9 55%, #6366f1 100%);
  --hsb-grad-hero:        radial-gradient(60% 60% at 15% 10%, rgba(34, 211, 238, 0.14) 0%, transparent 60%),
                          radial-gradient(50% 50% at 85% 20%, rgba(129, 140, 248, 0.12) 0%, transparent 60%);
  --hsb-grad-text:        linear-gradient(120deg, #e8f0f8 0%, #22d3ee 100%);

  --hsb-success:          #34d399;
  --hsb-success-bg:       rgba(52, 211, 153, 0.14);
  --hsb-warning:          #fbbf24;
  --hsb-warning-bg:       rgba(251, 191, 36, 0.14);
  --hsb-danger:           #f87171;
  --hsb-danger-bg:        rgba(248, 113, 113, 0.14);

  color-scheme: dark;
}

/* ---- Shared scale tokens (theme-independent) --------------------------- */

:root {
  --hsb-r-sm:   8px;
  --hsb-r-md:   12px;
  --hsb-r-lg:   18px;
  --hsb-r-xl:   26px;
  --hsb-r-pill: 999px;

  --hsb-s-1: 0.25rem;  --hsb-s-2: 0.5rem;   --hsb-s-3: 0.75rem;
  --hsb-s-4: 1rem;     --hsb-s-5: 1.5rem;   --hsb-s-6: 2rem;
  --hsb-s-7: 3rem;     --hsb-s-8: 4rem;

  --hsb-dur-fast: 150ms;
  --hsb-dur:      260ms;
  --hsb-dur-slow: 420ms;
  --hsb-ease:     cubic-bezier(0.22, 1, 0.36, 1);
  --hsb-ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --hsb-font: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --hsb-nav-h: 68px;
}

/* ---- 3. Base ----------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html { font-size: 100%; scroll-behavior: smooth; }

body.hsb {
  margin: 0;
  min-height: 100vh;
  font-family: var(--hsb-font);
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--hsb-text);
  background: var(--hsb-bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* NOTE — why there is no `transition: background-color/color` for the theme swap.
 *
 * The obvious implementation is to transition the themed properties on body and
 * the card surfaces. It does not work: when the value comes from an INHERITED
 * custom property (--hsb-bg changing on :root), the dependent transition latches
 * at its start value and never lands on the new colour. Measured directly —
 * body stayed at the light background indefinitely after switching to dark,
 * while sibling elements with no transition swapped correctly.
 *
 * So the animated swap is delivered by the View Transitions circular reveal in
 * hsb-theme.js, which animates a snapshot of the whole page and is both smoother
 * and cheaper than repainting every surface. Browsers without View Transitions
 * get an instant, correct swap — which beats a smooth, broken one.
 *
 * Transitions on interaction (hover, focus, press) live on the components
 * themselves and are unaffected, because those tokens are not changing.
 */

/* Set by the bootstrap and removed on load: kills the transition on the very
   first paint so the resolved theme never animates in from the wrong colour. */
.hsb-booting, .hsb-booting * { transition: none !important; }

h1, h2, h3, h4, h5 {
  margin: 0 0 var(--hsb-s-3);
  font-weight: 700;
  line-height: 1.18;
  letter-spacing: -0.022em;
  color: var(--hsb-text);
}

h1 { font-size: clamp(1.9rem, 3.4vw, 3rem); letter-spacing: -0.032em; }
h2 { font-size: clamp(1.5rem, 2.4vw, 2.15rem); letter-spacing: -0.026em; }
h3 { font-size: 1.2rem; }
h4 { font-size: 1.02rem; }

p { margin: 0 0 var(--hsb-s-4); color: var(--hsb-text-muted); }

a { color: var(--hsb-link); text-decoration: none; }
a:hover { color: var(--hsb-brand-strong); text-decoration: underline; }

img, svg { max-width: 100%; }

/* Keyboard focus — visible in BOTH themes, never removed. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--hsb-brand);
  outline-offset: 2px;
  border-radius: var(--hsb-r-sm);
}

/* Touch targets. Keyed on `pointer: coarse` rather than screen width, because
   what matters is whether a finger is doing the tapping — a 1024px tablet needs
   this and a 400px-wide desktop window does not. Compact controls (the small
   Back button, the password reveal, the theme toggle) measure 35-43px on a
   mouse-driven screen; this lifts every one of them to the 44px floor on touch. */
@media (pointer: coarse) {
  .hsb-btn,
  .hsb-btn-sm,
  .hsb-theme-toggle,
  .hsb-input-action,
  .hsb-nav-toggle,
  .hsb-tab {
    min-height: 44px;
    min-width: 44px;
  }
}

.hsb-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Skip link for keyboard users. */
.hsb-skip {
  position: absolute; left: 50%; top: 0;
  transform: translate(-50%, -120%);
  z-index: 200;
  padding: 0.6rem 1rem;
  background: var(--hsb-brand); color: var(--hsb-text-on-brand);
  border-radius: 0 0 var(--hsb-r-md) var(--hsb-r-md);
  font-weight: 600;
  transition: transform var(--hsb-dur) var(--hsb-ease);
}
.hsb-skip:focus { transform: translate(-50%, 0); color: var(--hsb-text-on-brand); }

/* ---- 4. Layout --------------------------------------------------------- */

.hsb-container {
  width: 100%;
  max-width: 1140px;
  margin-inline: auto;
  padding-inline: clamp(1rem, 3vw, 1.5rem);
}

.hsb-section { padding-block: clamp(3rem, 7vw, 5.5rem); }

.hsb-eyebrow {
  display: inline-flex; align-items: center; gap: 0.45rem;
  padding: 0.34rem 0.72rem;
  border-radius: var(--hsb-r-pill);
  background: var(--hsb-brand-soft);
  border: 1px solid var(--hsb-brand-ring);
  color: var(--hsb-brand);
  font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.07em; text-transform: uppercase;
}

.hsb-gradient-text {
  background: var(--hsb-grad-text);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}

/* ---- 5. Navigation ----------------------------------------------------- */

.hsb-nav {
  position: sticky; top: 0; z-index: 100;
  height: var(--hsb-nav-h);
  display: flex; align-items: center;
  background: var(--hsb-surface-glass);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--hsb-border);
}

.hsb-nav-inner { display: flex; align-items: center; gap: var(--hsb-s-4); width: 100%; }

.hsb-brand {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-weight: 800; font-size: 1rem; letter-spacing: -0.02em;
  color: var(--hsb-text);
}
.hsb-brand:hover { color: var(--hsb-text); }
.hsb-brand img { height: 30px; width: auto; display: block; }

.hsb-nav-links { display: flex; align-items: center; gap: 0.25rem; margin-left: auto; }

.hsb-nav-link {
  position: relative;
  padding: 0.45rem 0.75rem;
  border-radius: var(--hsb-r-sm);
  color: var(--hsb-text-muted);
  font-size: 0.875rem; font-weight: 500;
}
.hsb-nav-link:hover { color: var(--hsb-text); background: var(--hsb-surface-2); }
.hsb-nav-link::after {
  content: ''; position: absolute; left: 0.75rem; right: 0.75rem; bottom: 0.28rem;
  height: 2px; border-radius: 2px; background: var(--hsb-brand);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--hsb-dur) var(--hsb-ease);
}
.hsb-nav-link:hover::after, .hsb-nav-link[aria-current="page"]::after { transform: scaleX(1); }

.hsb-nav-actions { display: flex; align-items: center; gap: 0.5rem; }

/* Mobile menu */
.hsb-nav-toggle {
  display: none;
  width: 44px; height: 44px;
  align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--hsb-border);
  border-radius: var(--hsb-r-sm); color: var(--hsb-text); cursor: pointer;
}

@media (max-width: 991.98px) {
  .hsb-nav-toggle { display: inline-flex; }
  .hsb-nav-links {
    position: fixed; inset: var(--hsb-nav-h) 0 auto 0;
    flex-direction: column; align-items: stretch; gap: 0.15rem;
    margin: 0; padding: var(--hsb-s-4);
    background: var(--hsb-bg-elev);
    border-bottom: 1px solid var(--hsb-border);
    box-shadow: var(--hsb-shadow-lg);
    transform: translateY(-8px); opacity: 0; visibility: hidden;
    transition: transform var(--hsb-dur) var(--hsb-ease),
                opacity var(--hsb-dur) var(--hsb-ease),
                visibility var(--hsb-dur);
  }
  .hsb-nav-links[data-open="true"] { transform: translateY(0); opacity: 1; visibility: visible; }
  .hsb-nav-link { padding: 0.7rem 0.75rem; font-size: 0.95rem; }
  .hsb-nav-link::after { display: none; }
}

/* ---- 6. Buttons -------------------------------------------------------- */

.hsb-btn {
  --_bg: transparent; --_fg: var(--hsb-text); --_bd: var(--hsb-border-strong);
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: 0.45rem;
  min-height: 44px;                      /* touch target floor */
  padding: 0.6rem 1.15rem;
  border: 1px solid var(--_bd);
  border-radius: var(--hsb-r-md);
  background: var(--_bg); color: var(--_fg);
  font: inherit; font-size: 0.875rem; font-weight: 600;
  cursor: pointer; text-align: center;
  transition: transform var(--hsb-dur-fast) var(--hsb-ease),
              box-shadow var(--hsb-dur) var(--hsb-ease),
              background-color var(--hsb-dur) var(--hsb-ease),
              border-color var(--hsb-dur) var(--hsb-ease),
              opacity var(--hsb-dur-fast) linear;
}
.hsb-btn:hover { transform: translateY(-1px); color: var(--_fg); }
.hsb-btn:active { transform: translateY(0) scale(0.985); }   /* press feedback */
.hsb-btn[disabled], .hsb-btn[aria-disabled="true"] {
  opacity: 0.55; cursor: not-allowed; transform: none;
}

.hsb-btn-primary {
  --_bg: var(--hsb-grad-brand); --_fg: var(--hsb-text-on-brand); --_bd: transparent;
  box-shadow: 0 8px 20px -10px var(--hsb-brand-ring);
}
.hsb-btn-primary:hover { box-shadow: 0 12px 26px -10px var(--hsb-brand-ring); }

.hsb-btn-ghost { --_bg: var(--hsb-surface); --_fg: var(--hsb-text); --_bd: var(--hsb-border-strong); }
.hsb-btn-ghost:hover { --_bg: var(--hsb-surface-2); }

.hsb-btn-quiet { --_bd: transparent; --_fg: var(--hsb-text-muted); }
.hsb-btn-quiet:hover { --_fg: var(--hsb-text); --_bg: var(--hsb-surface-2); }

.hsb-btn-block { width: 100%; }

/* Loading state: swaps the label for a spinner without resizing the button. */
.hsb-btn[data-loading="true"] { pointer-events: none; }
.hsb-btn[data-loading="true"] .hsb-btn-label { opacity: 0; }
.hsb-btn[data-loading="true"]::after {
  content: ''; position: absolute;
  width: 1.05rem; height: 1.05rem;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%;
  animation: hsb-spin 0.6s linear infinite;
}
@keyframes hsb-spin { to { transform: rotate(360deg); } }

/* ---- 7. Forms ---------------------------------------------------------- */

.hsb-field {
  display: flex;
  flex-direction: column;
  gap: 0.5rem; /* 8px gap between label and input */
  margin-bottom: 0;
  box-sizing: border-box;
}

.hsb-label {
  font-size: 0.875rem; /* 14px */
  font-weight: 600;
  color: var(--hsb-text);
  line-height: 1.2;
}

.hsb-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
}

.hsb-input {
  width: 100%;
  height: 48px;
  min-height: 48px;
  padding: 0 1rem; /* 16px horizontal padding */
  font: inherit;
  font-size: 0.95rem; /* 15px-16px */
  color: var(--hsb-text);
  background: var(--hsb-surface);
  border: 1px solid var(--hsb-border-strong);
  border-radius: var(--hsb-r-md); /* 12px */
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--hsb-dur-fast) var(--hsb-ease),
              box-shadow var(--hsb-dur-fast) var(--hsb-ease),
              background-color var(--hsb-dur) var(--hsb-ease);
}
.hsb-input::placeholder {
  color: var(--hsb-text-subtle);
  opacity: 0.85;
}
.hsb-input:hover {
  border-color: var(--hsb-text-subtle);
}
.hsb-input:focus {
  outline: none;
  border-color: var(--hsb-brand);
  box-shadow: 0 0 0 3px var(--hsb-brand-ring);
}
.hsb-input:disabled {
  opacity: 0.6;
  cursor: not-allowed;
  background: var(--hsb-surface-2);
}
.hsb-input:-webkit-autofill,
.hsb-input:-webkit-autofill:hover,
.hsb-input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--hsb-text);
  -webkit-box-shadow: 0 0 0px 1000px var(--hsb-surface) inset;
  transition: background-color 5000s ease-in-out 0s;
}

/* Trailing control (password reveal) sits inside the field with min 48px right padding. */
.hsb-input-has-action .hsb-input {
  padding-right: 3.25rem; /* 52px */
}
.hsb-input-action {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  border-radius: var(--hsb-r-sm);
  color: var(--hsb-text-subtle);
  cursor: pointer;
  transition: color var(--hsb-dur-fast), background-color var(--hsb-dur-fast);
}
.hsb-input-action:hover {
  color: var(--hsb-text);
  background: var(--hsb-surface-2);
}
.hsb-input-action:focus-visible {
  outline: none;
  color: var(--hsb-brand);
  box-shadow: 0 0 0 2px var(--hsb-brand-ring);
}
.hsb-input-action .hsb-eye-off { display: none; }
.hsb-input-action[aria-pressed="true"] .hsb-eye-on { display: none; }
.hsb-input-action[aria-pressed="true"] .hsb-eye-off { display: block; }

/* Validation — reserves row space so error messages do not cause major layout jumps. */
.hsb-hint {
  font-size: 0.78rem;
  color: var(--hsb-text-subtle);
  margin: 0;
}
.hsb-field[data-state="error"] .hsb-input { border-color: var(--hsb-danger); }
.hsb-field[data-state="error"] .hsb-input:focus { box-shadow: 0 0 0 3px var(--hsb-danger-bg); }
.hsb-field[data-state="error"] .hsb-hint { color: var(--hsb-danger); }
.hsb-field[data-state="success"] .hsb-input { border-color: var(--hsb-success); }
.hsb-field[data-state="success"] .hsb-hint { color: var(--hsb-success); }

.hsb-check {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem; /* 8px gap between checkbox and text */
  font-size: 0.85rem;
  color: var(--hsb-text-muted);
  cursor: pointer;
  user-select: none;
  line-height: 1.3;
}
.hsb-check input[type="checkbox"] {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--hsb-brand);
  flex: 0 0 18px;
  cursor: pointer;
  border-radius: 4px;
}
.hsb-check input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--hsb-brand);
  outline-offset: 2px;
}

/* Password strength */
.hsb-strength { display: flex; gap: 4px; margin-top: 0.4rem; }
.hsb-strength span {
  height: 4px; flex: 1; border-radius: 2px;
  background: var(--hsb-surface-2);
  transition: background-color var(--hsb-dur) var(--hsb-ease);
}
.hsb-strength[data-score="1"] span:nth-child(-n+1) { background: var(--hsb-danger); }
.hsb-strength[data-score="2"] span:nth-child(-n+2) { background: var(--hsb-warning); }
.hsb-strength[data-score="3"] span:nth-child(-n+3) { background: #0ea5e9; }
.hsb-strength[data-score="4"] span { background: var(--hsb-success); }

/* Live requirement checklist, injected next to the meter by hsb-motion.js.
   The bar alone said "Weak" without saying what was missing, so people only
   discovered the real rules when the server rejected the form. Mirrors
   appValidatePassword() in password_policy.php. Uses both a tick and a weight
   change so state is not carried by colour alone. */
.hsb-pw-rules {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.2rem;
}
.hsb-pw-rule {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.78rem;
  line-height: 1.35;
  color: var(--hsb-text-muted);
  transition: color var(--hsb-dur) var(--hsb-ease);
}
.hsb-pw-mark {
  flex: none;
  position: relative;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  opacity: 0.55;
}
.hsb-pw-rule.is-met {
  /* Deliberately darker than --hsb-success. The token green measures ~3.6:1 on
     the light surface, which fails AA for text this size; this reads ~5.1:1.
     The tick below keeps the token colour — as a graphic it only needs 3:1. */
  color: #047857;
  font-weight: 600;
}
[data-theme="dark"] .hsb-pw-rule.is-met { color: var(--hsb-success); }
.hsb-pw-rule.is-met .hsb-pw-mark {
  opacity: 1;
  background: var(--hsb-success);
  border-color: var(--hsb-success);
}
.hsb-pw-rule.is-met .hsb-pw-mark::after {
  content: '';
  position: absolute;
  left: 4px;
  top: 1px;
  width: 4px;
  height: 8px;
  border: solid var(--hsb-surface, #fff);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
@media (prefers-reduced-motion: reduce) {
  .hsb-pw-rule { transition: none; }
}

/* ---- 8. Cards & surfaces ----------------------------------------------- */

.hsb-card {
  background: var(--hsb-surface);
  border: 1px solid var(--hsb-border);
  border-radius: var(--hsb-r-lg);
  box-shadow: var(--hsb-shadow);
}

.hsb-card-pad { padding: clamp(1.25rem, 3vw, 2rem); }

.hsb-feature {
  position: relative; overflow: hidden;
  padding: 1.35rem;
  background: var(--hsb-surface);
  border: 1px solid var(--hsb-border);
  border-radius: var(--hsb-r-lg);
  transition: transform var(--hsb-dur) var(--hsb-ease),
              box-shadow var(--hsb-dur) var(--hsb-ease),
              border-color var(--hsb-dur) var(--hsb-ease);
}
.hsb-feature:hover {
  transform: translateY(-4px);
  border-color: var(--hsb-brand-ring);
  box-shadow: var(--hsb-shadow-lg);
}
/* Gradient hairline that wipes in on hover. */
.hsb-feature::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: var(--hsb-grad-brand);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--hsb-dur-slow) var(--hsb-ease);
}
.hsb-feature:hover::before { transform: scaleX(1); }

.hsb-icon {
  display: inline-grid; place-items: center;
  width: 40px; height: 40px;
  border-radius: var(--hsb-r-md);
  background: var(--hsb-brand-soft);
  border: 1px solid var(--hsb-brand-ring);
  color: var(--hsb-brand);
  font-size: 1.05rem;
  margin-bottom: 0.85rem;
}

.hsb-panel {
  background: var(--hsb-bg-elev);
  border: 1px solid var(--hsb-border);
  border-radius: var(--hsb-r-lg);
}

/* ---- 9. Feedback ------------------------------------------------------- */

.hsb-alert {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.75rem 1rem;
  margin-bottom: 1.25rem; /* 20px margin bottom to separate from form/fields */
  border: 1px solid transparent;
  border-radius: var(--hsb-r-md); /* 12px */
  font-size: 0.875rem;
  line-height: 1.4;
  box-sizing: border-box;
}
.hsb-alert-error   { background: var(--hsb-danger-bg);  border-color: var(--hsb-danger);  color: var(--hsb-danger); }
.hsb-alert-success { background: var(--hsb-success-bg); border-color: var(--hsb-success); color: var(--hsb-success); }
.hsb-alert-warning { background: var(--hsb-warning-bg); border-color: var(--hsb-warning); color: var(--hsb-warning); }
.hsb-alert-info    { background: var(--hsb-brand-soft); border-color: var(--hsb-brand-ring); color: var(--hsb-brand); }

/* ---- 10. Theme toggle -------------------------------------------------- */

.hsb-theme-toggle {
  position: relative;
  width: 44px; height: 44px;
  display: inline-grid; place-items: center;
  background: var(--hsb-surface);
  border: 1px solid var(--hsb-border-strong);
  border-radius: var(--hsb-r-md);
  color: var(--hsb-text);
  cursor: pointer; overflow: hidden;
  transition: background-color var(--hsb-dur) var(--hsb-ease),
              border-color var(--hsb-dur) var(--hsb-ease);
}
.hsb-theme-toggle:hover { background: var(--hsb-surface-2); border-color: var(--hsb-brand-ring); }

/* Both icons are stacked; the inactive one rotates and scales out. */
.hsb-theme-toggle svg {
  grid-area: 1 / 1;
  width: 19px; height: 19px;
  transition: transform var(--hsb-dur-slow) var(--hsb-ease),
              opacity var(--hsb-dur) var(--hsb-ease);
}
:root[data-theme="light"] .hsb-theme-toggle .hsb-moon { transform: rotate(70deg) scale(0.4); opacity: 0; }
:root[data-theme="light"] .hsb-theme-toggle .hsb-sun  { transform: none; opacity: 1; }
:root[data-theme="dark"]  .hsb-theme-toggle .hsb-sun  { transform: rotate(-70deg) scale(0.4); opacity: 0; }
:root[data-theme="dark"]  .hsb-theme-toggle .hsb-moon { transform: none; opacity: 1; }

/* Circular reveal used by the View Transition path in hsb-theme.js. */
::view-transition-old(root), ::view-transition-new(root) {
  animation: none; mix-blend-mode: normal;
}
::view-transition-old(root) { z-index: 1; }
::view-transition-new(root) { z-index: 9999; }

/* ---- 11. Utilities ----------------------------------------------------- */

.hsb-grid { display: grid; gap: var(--hsb-s-4); }
.hsb-grid-2 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.hsb-grid-3 { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

.hsb-muted   { color: var(--hsb-text-muted); }
.hsb-subtle  { color: var(--hsb-text-subtle); }
.hsb-small   { font-size: 0.8rem; }
.hsb-center  { text-align: center; }
.hsb-stack   { display: flex; flex-direction: column; }
.hsb-row     { display: flex; align-items: center; }
.hsb-between { display: flex; align-items: center; justify-content: space-between; gap: var(--hsb-s-3); }
.hsb-wrap    { flex-wrap: wrap; }
.hsb-gap-2 { gap: var(--hsb-s-2); } .hsb-gap-3 { gap: var(--hsb-s-3); } .hsb-gap-4 { gap: var(--hsb-s-4); }
.hsb-mt-0 { margin-top: 0; } .hsb-mb-0 { margin-bottom: 0; }

/* ---- Footer ------------------------------------------------------------ */

.hsb-footer {
  background: var(--hsb-bg-elev);
  border-top: 1px solid var(--hsb-border);
  padding-block: var(--hsb-s-7) var(--hsb-s-5);
}
.hsb-footer h3 { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--hsb-text-subtle); }
.hsb-footer a { display: block; padding: 0.22rem 0; color: var(--hsb-text-muted); font-size: 0.85rem; }
.hsb-footer a:hover { color: var(--hsb-brand); }
.hsb-footer-bottom {
  margin-top: var(--hsb-s-5); padding-top: var(--hsb-s-4);
  border-top: 1px solid var(--hsb-border);
  font-size: 0.8rem; color: var(--hsb-text-subtle);
}
