/* ==========================================================================
   HostCrafter design system — tokens and primitives (ds.css)

   The written rules are docs/DESIGN-SYSTEM.md. Read that first; this file is
   the code half of it.

   INERT BY DESIGN. This file defines only --ds-* custom properties, .ds-*
   classes and ds-* keyframes. It styles no element, no existing class and no
   existing token, so loading it changes nothing on screen. A section adopts the
   system by using these names; until then it looks exactly as it did.

   WHY ON :root AND NOT ON #hc-root. The hosting panel's dialogs and toasts are
   appended to <body>, outside #hc-root, so every token the panel declares on
   #hc-root is undefined inside them — the bug that drew black boxes around
   tabs (see the panel-css-scoping memory). Tokens on :root reach the page, the
   panel, its dialogs and its toasts alike. .ds-* classes are global for the
   same reason.

   Dark mode follows the theme's explicit choice, html[data-hc-theme="dark"],
   never prefers-color-scheme on its own: honouring the OS once painted light
   text on a light panel.
   ========================================================================== */

:root {
  /* ---- brand -------------------------------------------------------------
     Navy is the product's colour (the sidebar, the selected state, the
     primary button). The vibrant accent is for focus, links and live state —
     the "dark + vibrant accent" of the brief. Orange is the call to buy and
     nothing else; ochre means "staging, not your live site" and nothing else. */
  --ds-brand:        #062e79;
  --ds-brand-2:      #00459e;   /* the sidebar gradient's bright end */
  --ds-brand-soft:   #e8eefa;
  --ds-brand-line:   #c3d3ea;
  --ds-accent:       #2563eb;
  --ds-accent-soft:  #eaf1ff;
  --ds-cta:          #f2691c;
  --ds-cta-hover:    #d45410;
  --ds-stage:        #c9701f;
  --ds-stage-soft:   #fdf2e7;

  /* ---- neutrals ----------------------------------------------------------
     Tinted, not white. The canvas carries a little blue so a white card has
     something to stand on; an all-white page was rejected as "only white
     containers looks so bad". */
  --ds-canvas:       #e9eef5;
  --ds-surface:      #ffffff;
  --ds-surface-2:    #f6f8fb;   /* sunk: table heads, wells, inputs at rest */
  --ds-surface-3:    #eef2f7;
  --ds-tint:         linear-gradient(165deg, #dfe9fb 0%, #ebf1fc 45%, #f3f7fd 100%);
  --ds-line:         #e1e6ee;
  --ds-line-2:       #cdd5e0;
  --ds-text:         #0f172a;
  --ds-text-2:       #334155;
  --ds-muted:        #64748b;
  --ds-faint:        #94a3b8;

  /* ---- status ------------------------------------------------------------ */
  --ds-ok:    #0e9f6e;  --ds-ok-soft:   #e7f7f0;  --ds-ok-line:   #b4e6d0;
  --ds-warn:  #c2700a;  --ds-warn-soft: #fff5e6;  --ds-warn-line: #f6d9a8;
  --ds-bad:   #d92d20;  --ds-bad-soft:  #fdeceb;  --ds-bad-line:  #f6c6c2;
  --ds-info:  #1d72e8;  --ds-info-soft: #eaf2fe;  --ds-info-line: #bcd6fb;

  /* ---- categorical: one hue per METRIC (identity, not status) -------------
     For telling usage metrics apart at a glance — the Plan Details rings.
     From the dataviz reference palette, in an order run through its
     validator on these card surfaces (2026-10-02): worst adjacent CVD ΔE 13.0
     light / 13.0 dark (target ≥ 8), normal-vision 27.5 / 24.6 (floor 15).
     Orange, yellow and red are left out on purpose — those are the warn and
     bad STATUS colours, and a metric must never look like a warning. cat-2
     and cat-5 sit under 3:1 on white, so they are only used beside a visible
     label. Fixed order: 1 websites, 2 storage, 3 bandwidth, 4 requests,
     5 databases. */
  --ds-cat-1: #2a78d6;  /* blue */
  --ds-cat-2: #e87ba4;  /* magenta */
  --ds-cat-3: #008300;  /* green */
  --ds-cat-4: #4a3aa7;  /* violet */
  --ds-cat-5: #1baf7a;  /* aqua */

  /* ---- type --------------------------------------------------------------
     The system stack until a webfont is chosen (open decision in the doc).
     Sizes step on a 1.125 scale from 13px; numbers use tabular figures. */
  --ds-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ds-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --ds-fs-xs: .75rem;    /* 12 — captions, badges */
  --ds-fs-sm: .8125rem;  /* 13 — secondary text, table cells */
  --ds-fs:    .875rem;   /* 14 — body in dense UI */
  --ds-fs-md: .9375rem;  /* 15 — body, menu items */
  --ds-fs-lg: 1.0625rem; /* 17 — card titles */
  --ds-fs-xl: 1.25rem;   /* 20 — section titles */
  --ds-fs-2x: 1.5rem;    /* 24 — stat values */
  --ds-fs-3x: 1.875rem;  /* 30 — hero numbers, sparingly */
  --ds-fw:      450;
  --ds-fw-med:  550;
  --ds-fw-semi: 650;
  --ds-fw-bold: 720;
  --ds-lh:      1.5;
  --ds-lh-tight: 1.2;

  /* ---- space: a 4px grid ------------------------------------------------- */
  --ds-1: 4px;  --ds-2: 8px;  --ds-3: 12px; --ds-4: 16px;
  --ds-5: 20px; --ds-6: 24px; --ds-8: 32px; --ds-10: 40px;

  /* ---- radius ------------------------------------------------------------ */
  --ds-r-sm: 6px;   /* buttons, inputs, chips */
  --ds-r:    8px;   /* menu items, small cards */
  --ds-r-lg: 12px;  /* cards, bento tiles */
  --ds-r-xl: 16px;  /* dialogs, the page's big panels */
  --ds-r-full: 999px;

  /* ---- elevation (soft UI) -----------------------------------------------
     Shadows are tinted with the navy, never pure black on light, and stay
     soft. e1 is a card at rest, e2 a card under the pointer, e3 a menu or
     popover, e4 a dialog. A hairline ring is part of e1 so a card holds its
     edge on a white ground without a heavy border. */
  --ds-e1: 0 0 0 1px rgba(15,23,42,.04), 0 1px 2px rgba(15,23,42,.05);
  --ds-e2: 0 0 0 1px rgba(15,23,42,.05), 0 2px 4px rgba(15,23,42,.05), 0 10px 24px -10px rgba(6,46,121,.22);
  --ds-e3: 0 0 0 1px rgba(15,23,42,.06), 0 16px 36px -12px rgba(6,46,121,.30);
  --ds-e4: 0 0 0 1px rgba(15,23,42,.06), 0 28px 70px -18px rgba(6,46,121,.42);
  --ds-ring: 0 0 0 3px rgba(37,99,235,.28);

  /* ---- glass -------------------------------------------------------------
     Subtle, and ONLY on things that float over content: the sticky top bar,
     dropdowns, dialogs, toasts, the command palette. Never on a card that sits
     in the page — glass over a flat canvas is just grey. */
  --ds-glass-bg:     rgba(255,255,255,.72);
  --ds-glass-line:   rgba(255,255,255,.65);
  --ds-glass-filter: saturate(160%) blur(14px);

  /* ---- motion ------------------------------------------------------------
     Fast and purposeful. Nothing loops except a spinner or a live dot, and
     nothing animates on scroll. Everything here is switched off under
     prefers-reduced-motion at the bottom of this file. */
  --ds-ease:        cubic-bezier(.2,.8,.2,1);    /* out — most things */
  --ds-ease-in-out: cubic-bezier(.65,0,.35,1);   /* moves across the screen */
  --ds-ease-spring: cubic-bezier(.34,1.56,.64,1);/* success pops only */
  --ds-t-fast: 120ms;   /* hover, press, colour */
  --ds-t:      180ms;   /* menus, tabs, small reveals */
  --ds-t-slow: 260ms;   /* dialogs, section change */
  --ds-stagger: 28ms;   /* per item in an entering list */

  /* ---- bento ------------------------------------------------------------- */
  --ds-bento-gap: 12px;
}

html[data-hc-theme="dark"] {
  /* Lifted and more saturated than the light values: on a dark ground the
     accent has to glow a little or it reads as a hole. */
  --ds-brand:        #7fa8e8;
  --ds-brand-2:      #9bbcef;
  --ds-brand-soft:   rgba(127,168,232,.14);
  --ds-brand-line:   rgba(127,168,232,.32);
  --ds-accent:       #5b8cff;
  --ds-accent-soft:  rgba(91,140,255,.14);
  --ds-cta:          #ff8a4c;
  --ds-cta-hover:    #ffa06b;
  --ds-stage:        #d9873f;
  --ds-stage-soft:   rgba(217,135,63,.15);

  --ds-canvas:       #0b0e14;
  --ds-surface:      #121720;
  --ds-surface-2:    #171d27;
  --ds-surface-3:    #1d2430;
  --ds-tint:         linear-gradient(165deg, #1a2440 0%, #151c2c 55%, #121826 100%);
  --ds-line:         #232b38;
  --ds-line-2:       #313a49;
  --ds-text:         #e6e9ef;
  --ds-text-2:       #c4cad4;
  --ds-muted:        #98a2b3;
  --ds-faint:        #6b7586;

  --ds-ok:    #3ccb8f;  --ds-ok-soft:   rgba(60,203,143,.13);  --ds-ok-line:   rgba(60,203,143,.3);
  --ds-warn:  #f0a640;  --ds-warn-soft: rgba(240,166,64,.13);  --ds-warn-line: rgba(240,166,64,.3);
  --ds-bad:   #f4675c;  --ds-bad-soft:  rgba(244,103,92,.13);  --ds-bad-line:  rgba(244,103,92,.3);
  --ds-info:  #5ea2ff;  --ds-info-soft: rgba(94,162,255,.13);  --ds-info-line: rgba(94,162,255,.3);

  --ds-e1: 0 0 0 1px rgba(255,255,255,.04), 0 1px 2px rgba(0,0,0,.4);
  --ds-e2: 0 0 0 1px rgba(255,255,255,.06), 0 10px 24px -10px rgba(0,0,0,.7);
  --ds-e3: 0 0 0 1px rgba(255,255,255,.07), 0 16px 36px -12px rgba(0,0,0,.75);
  --ds-e4: 0 0 0 1px rgba(255,255,255,.08), 0 28px 70px -18px rgba(0,0,0,.8);
  --ds-ring: 0 0 0 3px rgba(91,140,255,.35);

  --ds-glass-bg:     rgba(18,23,32,.72);
  --ds-glass-line:   rgba(255,255,255,.08);

  /* the same five hues, stepped for the dark surface (validated as a set) */
  --ds-cat-1: #3987e5;
  --ds-cat-2: #d55181;
  --ds-cat-3: #008300;
  --ds-cat-4: #9085e9;
  --ds-cat-5: #199e70;
}

/* ==========================================================================
   Primitives. Every one is a class you opt into; none touches existing markup.
   ========================================================================== */

/* ---- card ---------------------------------------------------------------- */
.ds-card {
  background: var(--ds-surface); border-radius: var(--ds-r-lg);
  box-shadow: var(--ds-e1); padding: var(--ds-4);
  transition: box-shadow var(--ds-t) var(--ds-ease), transform var(--ds-t) var(--ds-ease);
}
.ds-card--tint { background: var(--ds-tint); }
.ds-card--interactive { cursor: pointer; }
.ds-card--interactive:hover { box-shadow: var(--ds-e2); transform: translateY(-1px); }
.ds-card--interactive:active { transform: translateY(0) scale(.997); }
.ds-card__title { margin: 0; font-size: var(--ds-fs-lg); font-weight: var(--ds-fw-semi); color: var(--ds-text); line-height: var(--ds-lh-tight); }
.ds-card__sub { margin: var(--ds-1) 0 0; font-size: var(--ds-fs-sm); color: var(--ds-muted); }

/* ---- bento grid ----------------------------------------------------------
   Twelve columns; a tile says how many it spans. Six columns on a tablet,
   one on a phone. Tiles are dense: a bento grid here is a way to put more on
   one screen, not a way to put less on it in bigger boxes. */
.ds-bento {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--ds-bento-gap); grid-auto-flow: dense;
}
.ds-span-2  { grid-column: span 2; }
.ds-span-3  { grid-column: span 3; }
.ds-span-4  { grid-column: span 4; }
.ds-span-5  { grid-column: span 5; }
.ds-span-6  { grid-column: span 6; }
.ds-span-7  { grid-column: span 7; }
.ds-span-8  { grid-column: span 8; }
.ds-span-12 { grid-column: span 12; }
.ds-row-2   { grid-row: span 2; }
@media (max-width: 991.98px) {
  .ds-bento { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .ds-span-2, .ds-span-3 { grid-column: span 3; }
  .ds-span-4, .ds-span-5, .ds-span-6, .ds-span-7, .ds-span-8, .ds-span-12 { grid-column: span 6; }
}
@media (max-width: 575.98px) {
  .ds-bento { grid-template-columns: minmax(0, 1fr); }
  .ds-bento > * { grid-column: auto; grid-row: auto; }
}

/* Container-aware bento. Inside the hosting panel a section is far narrower
   than the window — two menus sit beside it — so viewport breakpoints ask the
   wrong question. Put .ds-cq on a wrapper and the .ds-bento inside it adapts
   to the width it actually has. (Added for the Image Optimizer, 2026-10-02.) */
.ds-cq { container: ds-cq / inline-size; }
@container ds-cq (max-width: 860px) {
  .ds-bento { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .ds-span-2, .ds-span-3 { grid-column: span 3; }
  .ds-span-4, .ds-span-5, .ds-span-6, .ds-span-7, .ds-span-8, .ds-span-12 { grid-column: span 6; }
}
@container ds-cq (max-width: 480px) {
  .ds-bento { grid-template-columns: minmax(0, 1fr); }
  .ds-bento > * { grid-column: auto; grid-row: auto; }
}

/* Card header: an eyebrow title on the left, an action or a chip on the right. */
.ds-card__head { display: flex; align-items: center; justify-content: space-between; gap: var(--ds-3); margin-bottom: var(--ds-3); }
.ds-eyebrow {
  font-size: var(--ds-fs-xs); font-weight: var(--ds-fw-semi); letter-spacing: .06em;
  text-transform: uppercase; color: var(--ds-muted);
}

/* A stat tile: an icon well, a label, a value, an optional foot. */
.ds-tile { display: flex; flex-direction: column; gap: var(--ds-2); min-width: 0; }
.ds-tile__top { display: flex; align-items: center; gap: var(--ds-2); }
.ds-tile__ic {
  width: 34px; height: 34px; border-radius: 10px; flex-shrink: 0;
  display: grid; place-items: center; background: var(--ds-brand-soft); color: var(--ds-brand);
}
.ds-tile__ic svg, .ds-tile__ic i { width: 18px; height: 18px; font-size: 1rem; }
.ds-tile__label { font-size: var(--ds-fs-sm); font-weight: var(--ds-fw-med); color: var(--ds-muted); }
.ds-tile__value {
  font-size: var(--ds-fs-2x); font-weight: var(--ds-fw-bold); color: var(--ds-text);
  line-height: 1.1; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.ds-tile__foot { font-size: var(--ds-fs-xs); color: var(--ds-muted); }

/* ---- buttons -------------------------------------------------------------
   One shape, five intents. Press sinks by a pixel; focus is always visible. */
.ds-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--ds-2);
  height: 34px; padding: 0 var(--ds-3); border-radius: var(--ds-r-sm);
  font: inherit; font-size: var(--ds-fs); font-weight: var(--ds-fw-semi); line-height: 1;
  white-space: nowrap; text-decoration: none; cursor: pointer;
  border: 1px solid var(--ds-line-2); background: var(--ds-surface); color: var(--ds-text-2);
  box-shadow: 0 1px 1px rgba(15,23,42,.04);
  transition: background var(--ds-t-fast) var(--ds-ease), border-color var(--ds-t-fast) var(--ds-ease),
              color var(--ds-t-fast) var(--ds-ease), box-shadow var(--ds-t-fast) var(--ds-ease),
              transform var(--ds-t-fast) var(--ds-ease);
}
.ds-btn:hover { background: var(--ds-surface-2); border-color: var(--ds-faint); color: var(--ds-text); text-decoration: none; }
.ds-btn:active { transform: translateY(1px); }
.ds-btn:focus-visible { outline: 0; box-shadow: var(--ds-ring); }
.ds-btn[disabled], .ds-btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }
.ds-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.ds-btn--primary { background: var(--ds-brand); border-color: var(--ds-brand); color: #fff; }
.ds-btn--primary:hover { background: #0a3a92; border-color: #0a3a92; color: #fff; }
html[data-hc-theme="dark"] .ds-btn--primary { color: #0b0e14; }
html[data-hc-theme="dark"] .ds-btn--primary:hover { background: var(--ds-brand-2); border-color: var(--ds-brand-2); color: #0b0e14; }
.ds-btn--cta { background: var(--ds-cta); border-color: var(--ds-cta); color: #fff; }
.ds-btn--cta:hover { background: var(--ds-cta-hover); border-color: var(--ds-cta-hover); color: #fff; }
/* A secondary action that should still read as an action (the region's
   "Change"): the brand's soft wash, brand text. */
.ds-btn--soft { background: var(--ds-brand-soft); border-color: transparent; color: var(--ds-brand); box-shadow: none; }
.ds-btn--soft:hover { background: var(--ds-brand-line); border-color: transparent; color: var(--ds-brand); }
/* On a dark brand surface (the Plan Details card): white, navy text. */
.ds-btn--light { background: #fff; border-color: #fff; color: #062e79; box-shadow: 0 6px 16px -8px rgba(0,0,0,.45); }
.ds-btn--light:hover { background: #eaf0fb; border-color: #eaf0fb; color: #062e79; }
.ds-btn--ghost { background: transparent; border-color: transparent; box-shadow: none; }
.ds-btn--ghost:hover { background: var(--ds-surface-3); border-color: transparent; }
.ds-btn--danger { color: var(--ds-bad); border-color: var(--ds-bad-line); }
.ds-btn--danger:hover { background: var(--ds-bad); border-color: var(--ds-bad); color: #fff; }
.ds-btn--sm { height: 28px; padding: 0 var(--ds-2); font-size: var(--ds-fs-sm); }
.ds-btn--lg { height: 40px; padding: 0 var(--ds-4); font-size: var(--ds-fs-md); }
.ds-btn--icon { width: 34px; padding: 0; }

/* Loading and success states on any button: add .is-loading, then .is-done.
   The label stays in the layout (only hidden), so the button never changes
   width under the pointer. */
.ds-btn { position: relative; }
.ds-btn.is-loading, .ds-btn.is-done { color: transparent !important; pointer-events: none; }
.ds-btn.is-loading::after, .ds-btn.is-done::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 16px; height: 16px;
}
.ds-btn.is-loading::after {
  border-radius: 50%; border: 2px solid currentColor; border-color: var(--ds-faint);
  border-top-color: var(--ds-text); animation: ds-spin .7s linear infinite;
}
.ds-btn--primary.is-loading::after, .ds-btn--cta.is-loading::after { border-color: rgba(255,255,255,.4); border-top-color: #fff; }
.ds-btn.is-done::after {
  width: 9px; height: 15px; margin-top: 7px; border: solid var(--ds-ok); border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg); animation: ds-pop var(--ds-t-slow) var(--ds-ease-spring);
}
.ds-btn--primary.is-done::after, .ds-btn--cta.is-done::after { border-color: #fff; }

/* ---- badges and live dot ------------------------------------------------- */
.ds-badge {
  display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px;
  border-radius: var(--ds-r-full); font-size: var(--ds-fs-xs); font-weight: var(--ds-fw-semi);
  background: var(--ds-surface-3); color: var(--ds-muted); white-space: nowrap;
}
.ds-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ds-badge--plain::before { display: none; }
.ds-badge--ok   { background: var(--ds-ok-soft);   color: var(--ds-ok); }
.ds-badge--warn { background: var(--ds-warn-soft); color: var(--ds-warn); }
.ds-badge--bad  { background: var(--ds-bad-soft);  color: var(--ds-bad); }
.ds-badge--info { background: var(--ds-info-soft); color: var(--ds-info); }
.ds-badge--brand{ background: var(--ds-brand-soft); color: var(--ds-brand); }
/* Staging only: "this is a rehearsal, not your live site". No other use. */
.ds-badge--stage{ background: var(--ds-stage-soft); color: var(--ds-stage); }
.ds-dot { position: relative; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--ds-ok); }
.ds-dot--live::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%; background: inherit;
  animation: ds-pulse 1.8s var(--ds-ease) infinite;
}

/* ---- segmented control (Linear-style tabs) ------------------------------- */
.ds-seg {
  display: inline-flex; gap: 2px; padding: 3px; border-radius: var(--ds-r);
  background: var(--ds-surface-3); max-width: 100%; overflow-x: auto;
}
.ds-seg button {
  border: 0; background: transparent; font: inherit; font-size: var(--ds-fs-sm);
  font-weight: var(--ds-fw-med); color: var(--ds-muted); padding: 6px 12px;
  border-radius: 6px; cursor: pointer; white-space: nowrap;
  transition: background var(--ds-t-fast) var(--ds-ease), color var(--ds-t-fast) var(--ds-ease), box-shadow var(--ds-t-fast) var(--ds-ease);
}
.ds-seg button:hover { color: var(--ds-text); }
.ds-seg button[aria-selected="true"], .ds-seg button.is-on {
  background: var(--ds-surface); color: var(--ds-text); box-shadow: var(--ds-e1);
}
.ds-seg button:focus-visible { outline: 0; box-shadow: var(--ds-ring); }

/* ---- inputs -------------------------------------------------------------- */
.ds-input {
  width: 100%; height: 36px; padding: 0 var(--ds-3); border-radius: var(--ds-r-sm);
  border: 1px solid var(--ds-line-2); background: var(--ds-surface); color: var(--ds-text);
  font: inherit; font-size: var(--ds-fs);
  transition: border-color var(--ds-t-fast) var(--ds-ease), box-shadow var(--ds-t-fast) var(--ds-ease);
}
.ds-input::placeholder { color: var(--ds-faint); }
.ds-input:hover { border-color: var(--ds-faint); }
.ds-input:focus { outline: 0; border-color: var(--ds-accent); box-shadow: var(--ds-ring); }

/* ---- choice list (a radio group as rows) ---------------------------------
   For picking one of a few options where each option carries a fact — the
   Image Optimizer's formats, each with what it saves. Buttons with
   role="radio"; .is-on marks the chosen one. */
.ds-choice { display: flex; flex-direction: column; gap: 6px; }
.ds-choice__opt {
  display: flex; align-items: center; gap: var(--ds-3); width: 100%; text-align: left;
  padding: 10px 12px; border-radius: var(--ds-r); border: 1px solid var(--ds-line);
  background: var(--ds-surface); color: var(--ds-text-2); font: inherit; cursor: pointer;
  transition: border-color var(--ds-t-fast) var(--ds-ease), background var(--ds-t-fast) var(--ds-ease),
              box-shadow var(--ds-t-fast) var(--ds-ease);
}
.ds-choice__opt:hover:not([disabled]) { border-color: var(--ds-line-2); background: var(--ds-surface-2); }
.ds-choice__opt.is-on {
  border-color: var(--ds-brand); background: var(--ds-brand-soft); color: var(--ds-text);
  box-shadow: inset 0 0 0 1px var(--ds-brand);
}
.ds-choice__opt[disabled] { opacity: .5; cursor: not-allowed; }
.ds-choice__opt:focus-visible { outline: 0; box-shadow: var(--ds-ring); }
.ds-choice__dot {
  position: relative; width: 16px; height: 16px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid var(--ds-line-2); transition: border-color var(--ds-t-fast) var(--ds-ease);
}
.ds-choice__opt.is-on .ds-choice__dot { border-color: var(--ds-brand); }
.ds-choice__opt.is-on .ds-choice__dot::after {
  content: ""; position: absolute; inset: 2px; border-radius: 50%; background: var(--ds-brand);
  animation: ds-dot-in var(--ds-t) var(--ds-ease-spring);
}
.ds-choice__label { font-size: var(--ds-fs-md); font-weight: var(--ds-fw-semi); }
.ds-choice__tag {
  font-size: 10.5px; font-weight: var(--ds-fw-bold); letter-spacing: .05em; text-transform: uppercase;
  padding: 1px 6px; border-radius: var(--ds-r-full); background: var(--ds-ok-soft); color: var(--ds-ok);
}
.ds-choice__meta {
  margin-left: auto; text-align: right; white-space: nowrap; font-size: var(--ds-fs-sm);
  color: var(--ds-muted); font-variant-numeric: tabular-nums;
}
.ds-choice__meta b { color: var(--ds-ok); font-weight: var(--ds-fw-semi); }

/* ---- key / value list ---------------------------------------------------- */
.ds-kv { display: flex; flex-direction: column; }
.ds-kv__row {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--ds-3);
  padding: 7px 0; border-top: 1px solid var(--ds-line); font-size: var(--ds-fs-sm);
}
.ds-kv__row:first-child { border-top: 0; padding-top: 0; }
.ds-kv__row:last-child { padding-bottom: 0; }
.ds-kv__k { color: var(--ds-muted); }
.ds-kv__v { color: var(--ds-text); font-weight: var(--ds-fw-med); text-align: right; font-variant-numeric: tabular-nums; }

/* ---- meter (labelled bars) -----------------------------------------------
   Rows of label · bar · value, aligned as a grid so several bars compare at
   a glance. Set the fill's width inline; it eases to it. */
.ds-meter { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 8px 12px; }
.ds-meter__k { font-size: var(--ds-fs-sm); font-weight: var(--ds-fw-med); color: var(--ds-muted); }
.ds-meter__track { height: 8px; border-radius: var(--ds-r-full); background: var(--ds-surface-3); overflow: hidden; }
.ds-meter__fill { height: 100%; width: 0; border-radius: inherit; background: var(--ds-brand); transition: width 700ms var(--ds-ease); }
.ds-meter__fill--ok { background: var(--ds-ok); }
.ds-meter__fill--muted { background: var(--ds-faint); }
/* Usage against an allowance: amber from 75%, red from 90% (Plan Details). */
.ds-meter__fill--warn { background: var(--ds-warn); }
.ds-meter__fill--bad { background: var(--ds-bad); }
.ds-meter__v { font-size: var(--ds-fs-sm); font-weight: var(--ds-fw-semi); color: var(--ds-text); text-align: right; font-variant-numeric: tabular-nums; }

/* ---- glass (floating layers only) ---------------------------------------- */
.ds-glass {
  background: var(--ds-glass-bg); border: 1px solid var(--ds-glass-line);
  -webkit-backdrop-filter: var(--ds-glass-filter); backdrop-filter: var(--ds-glass-filter);
}
/* Where backdrop-filter does not exist the translucent fill would just look
   washed out, so it becomes the solid surface instead. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .ds-glass { background: var(--ds-surface); }
}

/* ---- skeleton ------------------------------------------------------------ */
.ds-skel {
  position: relative; overflow: hidden; border-radius: 6px;
  background: var(--ds-surface-3); min-height: 10px;
}
.ds-skel::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent);
  animation: ds-shimmer 1.3s var(--ds-ease-in-out) infinite;
}
html[data-hc-theme="dark"] .ds-skel::after { background: linear-gradient(90deg, transparent, rgba(255,255,255,.06), transparent); }

/* ---- entrance (section change, list arrival) -----------------------------
   Put .ds-enter on what just arrived; give list items style="--ds-i:N" to
   stagger them. Opacity and 6px of rise only — no slide from offscreen, no
   scroll trigger. */
.ds-enter { animation: ds-rise var(--ds-t-slow) var(--ds-ease) both; animation-delay: calc(var(--ds-i, 0) * var(--ds-stagger)); }
.ds-fade  { animation: ds-fade var(--ds-t) var(--ds-ease) both; }
.ds-scale-in { animation: ds-scale-in var(--ds-t-slow) var(--ds-ease) both; }

@keyframes ds-rise     { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
@keyframes ds-fade     { from { opacity: 0; } to { opacity: 1; } }
@keyframes ds-scale-in { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }
@keyframes ds-spin     { to { transform: rotate(360deg); } }
@keyframes ds-shimmer  { to { transform: translateX(100%); } }
@keyframes ds-pulse    { 0% { transform: scale(1); opacity: .6; } 100% { transform: scale(2.6); opacity: 0; } }
@keyframes ds-pop      { 0% { opacity: 0; transform: rotate(45deg) scale(.4); } 100% { opacity: 1; transform: rotate(45deg) scale(1); } }
@keyframes ds-dot-in   { from { transform: scale(.2); } to { transform: none; } }

/* ---- reduced motion: every ds animation and transition off --------------- */
@media (prefers-reduced-motion: reduce) {
  .ds-card, .ds-btn, .ds-seg button, .ds-input, .ds-choice__opt, .ds-meter__fill { transition: none; }
  .ds-enter, .ds-fade, .ds-scale-in, .ds-skel::after, .ds-dot--live::after,
  .ds-btn.is-loading::after, .ds-btn.is-done::after, .ds-choice__opt.is-on .ds-choice__dot::after { animation: none; }
  .ds-card--interactive:hover { transform: none; }
}
