/* =====================================================================
   Design System — BASE COMPONENTS  v0.3.0
   Reusable primitives built ONLY on tokens.css. Plain CSS, framework-
   agnostic. Import after tokens.css. Class prefix: ds-
   Ships in two layers: ds.base (root + a11y globals + type helpers, kept
   LOW so apps can override) and ds.components (the ds-* primitives).
   ===================================================================== */

@layer ds.base{
.ds-root{
  color:var(--c-txt);
  font:var(--fs-15)/var(--lh) var(--font);
  background:var(--c-bg-grad), var(--c-bg);
  -webkit-font-smoothing:antialiased;
}
.ds *{box-sizing:border-box}

/* ---- accessibility globals ---- */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--c-focus); outline-offset:2px; border-radius:var(--r-sm);
}
@media (prefers-reduced-motion:reduce){
  *,::before,::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
}
/* accent-tinted text selection — auto-neutralizes to the client's accent */
::selection{background:color-mix(in srgb,var(--c-accent) 28%,transparent);color:var(--c-txt)}

/* ---- typography ---- */
.ds-h1{font-family:var(--font-display);font-size:var(--fs-24);font-weight:var(--fw-bold);letter-spacing:var(--tracking-display);line-height:var(--lh-tight);margin:0}
.ds-h2{font-family:var(--font-display);font-size:var(--fs-18);font-weight:var(--fw-semi);letter-spacing:-.01em;margin:0}
.ds-eyebrow{font-size:var(--fs-11);text-transform:uppercase;letter-spacing:.08em;font-weight:var(--fw-semi);color:var(--c-muted)}
.ds-muted{color:var(--c-muted)} .ds-dim{color:var(--c-txt-2)}
/* ---- lead / standfirst (section intro paragraph) ----
   Deliberately full-width: a lead sits above full-width content (tables,
   figure/card grids), so it shares that column instead of being capped to a
   reading measure — a narrow per-paragraph cap makes the intro look "cut off"
   next to the wide content directly below it. Want a measure? Constrain the
   CONTAINER, not the lead. */
.ds-lead{font-size:var(--fs-18);line-height:var(--lh);color:var(--c-txt-2);margin:0;max-width:none}
.ds-link{color:var(--c-accent);text-decoration:none} .ds-link:hover{text-decoration:underline}
.ds-hl{background:color-mix(in srgb,var(--c-accent) 22%,transparent);padding:.06em .18em;border-radius:3px;box-decoration-break:clone;-webkit-box-decoration-break:clone}
/* Ink-safe display text — never clip the last line's descender ink. A line-height
   below ~1.25 (the --lh-tight floor) makes glyph ink overflow the box; it only
   renders because overflow is visible, so it gets CLIPPED the moment the box is
   composited (transform/will-change/opacity animation), clipped (overflow!=visible),
   printed, or filled via background-clip:text (descender below the box = no fill).
   The padding extends the box (and the clip/fill region) past the ink; the negative
   margin keeps layout identical. For an element with its own bottom margin, fold the
   offset into it instead: margin-block-end:calc(<margin> - .15em). */
.ds-ink-safe{padding-block-end:.15em;margin-block-end:-.15em}
}

@layer ds.components{
/* ---- icon (Lucide standard; the system uses NO emoji) ----
   Paste a Lucide SVG (lucide.dev, ISC-licensed), give it class="ds-icon": it
   inherits currentColor (themes for free), sizes to 1em so it matches adjacent
   text, and takes its stroke weight from a token. Reach for an icon wherever
   you'd otherwise drop an emoji. Sizes: default 1em (inline), -lg, -2xl. */
.ds-icon{width:var(--icon);height:var(--icon);flex:none;display:inline-block;vertical-align:-.125em;
  fill:none;stroke:currentColor;stroke-width:var(--icon-stroke);stroke-linecap:round;stroke-linejoin:round}
.ds-icon-lg{--icon:1.4em} .ds-icon-2xl{--icon:2.4em}

/* ---- button ---- */
.ds-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-1);min-height:36px;
  border:1px solid var(--c-line-2);background:var(--c-surface-2);color:var(--c-txt);
  border-radius:9px;padding:7px 13px;font:var(--fw-medium) var(--fs-13)/1 var(--font);
  cursor:pointer;transition:all var(--t);white-space:nowrap;text-decoration:none}
.ds-btn:hover{border-color:var(--c-accent);transform:var(--lift-1)}
.ds-btn:active{transform:none}
.ds-btn-primary{background:var(--c-accent);border-color:var(--c-accent);color:var(--c-on-accent);font-weight:var(--fw-semi)}
.ds-btn-primary:hover{filter:brightness(1.08)}
.ds-btn-good{background:color-mix(in srgb,var(--c-good) 14%,transparent);border-color:color-mix(in srgb,var(--c-good) 45%,transparent);color:var(--c-good)}
.ds-btn-good:hover{background:color-mix(in srgb,var(--c-good) 22%,transparent);border-color:var(--c-good)}
.ds-btn-ghost{background:transparent}
.ds-btn-danger{color:var(--c-muted)} .ds-btn-danger:hover{border-color:var(--c-danger);color:var(--c-danger)}
/* pill CTA with lift — borrowed from the proposal/landing projects */
.ds-btn-pill{min-height:auto;border-radius:var(--r-pill);padding:.8rem 1.8rem;font-size:var(--fs-15);
  background:var(--c-accent);border-color:transparent;color:var(--c-on-accent);font-weight:var(--fw-semi);
  box-shadow:0 8px 22px -8px color-mix(in srgb,var(--c-accent) 60%,transparent);transition:transform var(--t),box-shadow var(--t-slow)}
.ds-btn-pill:hover{transform:var(--lift-2) scale(1.015)}

/* ---- card ---- */
.ds-card{background:var(--c-surface);border:1px solid var(--c-line);border-radius:var(--r-lg);
  padding:var(--sp-4) calc(var(--sp-4) + 2px);box-shadow:var(--sh-1);transition:border-color var(--t),background var(--t),transform var(--t)}
.ds-card:hover{border-color:var(--c-line-2);background:var(--c-surface-hover)}
/* KPI / stat tile with severity rail — borrowed from the accounting dashboard */
.ds-kpi{background:var(--c-surface);border:1px solid var(--c-line);border-top:3px solid var(--sev,var(--c-accent));
  border-radius:var(--r-lg);padding:var(--sp-3) var(--sp-4);box-shadow:var(--sh-1);transition:transform var(--t),border-color var(--t)}
.ds-kpi:hover{transform:var(--lift-2)}
.ds-kpi .val{font-family:var(--font-display);font-size:var(--fs-30);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;letter-spacing:var(--tracking-display)}
.ds-kpi .lbl{color:var(--c-muted);font-size:var(--fs-12);text-transform:uppercase;letter-spacing:.05em}

/* ---- signature rail (reusable accent edge — the recurring 'tell') ----
   Add .ds-rail to any panel/card/callout/active row for the gradient
   left edge the nav item uses. Collapses to a flat accent bar when a
   client sets accent-2 = accent. */
.ds-rail{position:relative}
.ds-rail::before{content:"";position:absolute;inset-block:0;inset-inline-start:0;width:3px;
  border-radius:3px 0 0 3px;background:var(--grad-signature-v)}

/* ---- badge / chip ---- */
.ds-badge{font-size:var(--fs-11);font-weight:var(--fw-bold);letter-spacing:.02em;text-transform:uppercase;padding:3px 8px;border-radius:6px;white-space:nowrap}
.ds-badge-accent{background:color-mix(in srgb,var(--c-accent) 14%,transparent);color:var(--c-accent)}
.ds-badge-good{background:color-mix(in srgb,var(--c-good) 14%,transparent);color:var(--c-good)}
.ds-badge-warn{background:color-mix(in srgb,var(--c-warn) 15%,transparent);color:var(--c-warn)}
.ds-badge-info{background:color-mix(in srgb,var(--c-info) 15%,transparent);color:var(--c-info)}
.ds-chip{background:var(--c-surface-2);border:1px solid var(--c-line);border-radius:var(--r-pill);padding:1px 9px;font-size:var(--fs-12);color:var(--c-muted);font-variant-numeric:tabular-nums}

/* ---- form field (label + input + help/error) ---- */
.ds-field{display:flex;flex-direction:column;gap:5px}
.ds-field > label{font-size:var(--fs-13);color:var(--c-txt-2);font-weight:var(--fw-medium)}
.ds-field .help{font-size:var(--fs-12);color:var(--c-muted)}
.ds-field .err{font-size:var(--fs-12);color:var(--c-danger)}
.ds-input,.ds-textarea,.ds-select{background:var(--c-surface);border:1px solid var(--c-line-2);color:var(--c-txt);
  border-radius:9px;padding:8px 11px;font:var(--fs-14) var(--font);transition:border-color var(--t)}
.ds-input:focus,.ds-textarea:focus,.ds-select:focus{outline:none;border-color:var(--c-accent)}
.ds-field[data-invalid] .ds-input{border-color:var(--c-danger)}

/* ---- nav item (sidebar) ---- */
.ds-navitem{position:relative;display:flex;align-items:center;justify-content:space-between;gap:var(--sp-2);
  padding:9px 11px;border-radius:var(--r-sm);color:var(--c-txt-2);text-decoration:none;font-size:var(--fs-14);
  cursor:pointer;transition:background var(--t),color var(--t)}
.ds-navitem:hover{background:var(--c-surface);color:var(--c-txt)}
.ds-navitem.is-active{background:var(--c-surface-2);color:var(--c-txt);font-weight:var(--fw-medium)}
.ds-navitem.is-active::before{content:"";position:absolute;left:-14px;top:8px;bottom:8px;width:3px;border-radius:0 3px 3px 0;
  background:var(--grad-signature-v)}

/* ---- meter (progress / relevance) ---- */
.ds-meter{height:5px;background:var(--c-surface-2);border-radius:3px;overflow:hidden;max-width:170px}
.ds-meter > i{display:block;height:100%;border-radius:3px;background:var(--grad-signature)}

/* ---- empty state (the moment most systems leave blank) ---- */
.ds-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--sp-2);padding:var(--sp-12) var(--sp-6);color:var(--c-txt-2)}
.ds-empty::before{content:"";width:44px;height:3px;border-radius:3px;background:var(--grad-signature);margin-bottom:var(--sp-1)}
.ds-empty .t{font-family:var(--font-display);font-size:var(--fs-18);font-weight:var(--fw-semi);color:var(--c-txt)}
.ds-empty .d{font-size:var(--fs-14);color:var(--c-muted);max-width:42ch}

/* ---- callout / alert (left-accent panel, 4 tones) ---- */
.ds-callout,.ds-alert{background:linear-gradient(90deg,color-mix(in srgb,var(--tone,var(--c-accent)) 9%,transparent),transparent);
  border-left:3px solid var(--tone,var(--c-accent));border-radius:var(--r-sm);padding:10px 13px;font-size:var(--fs-13);color:var(--c-txt-2)}
.ds-callout b,.ds-alert b{color:var(--c-txt)}
.ds-alert-info{--tone:var(--c-info)} .ds-alert-good{--tone:var(--c-good)} .ds-alert-warn{--tone:var(--c-warn)} .ds-alert-danger{--tone:var(--c-danger)}

/* ---- table ---- */
.ds-table{width:100%;border-collapse:collapse;font-size:var(--fs-14)}
.ds-table th{text-align:left;font-weight:var(--fw-semi);color:var(--c-txt-2);font-size:var(--fs-12);text-transform:uppercase;letter-spacing:.04em;
  background:var(--c-surface-2);padding:9px 12px;position:sticky;top:0}
.ds-table td{padding:10px 12px;border-top:1px solid var(--c-line);font-variant-numeric:tabular-nums}
.ds-table tbody tr:hover{background:var(--c-surface-hover)}

/* ---- code ---- */
.ds-code{font-family:var(--font-mono);font-size:.9em;background:var(--c-surface-2);border:1px solid var(--c-line);border-radius:6px;padding:1px 6px}
.ds-pre{font-family:var(--font-mono);font-size:var(--fs-13);background:var(--c-surface-2);border:1px solid var(--c-line);border-radius:var(--r);
  padding:var(--sp-3) var(--sp-4);overflow:auto;line-height:1.5}
.ds-pre code{all:unset;white-space:pre}

/* ---- tabs + segmented control ---- */
.ds-tabs{display:flex;gap:var(--sp-4);border-bottom:1px solid var(--c-line)}
.ds-tabs > a{padding:9px 2px;color:var(--c-muted);text-decoration:none;font-size:var(--fs-14);border-bottom:2px solid transparent;margin-bottom:-1px}
.ds-tabs > a.is-active{color:var(--c-txt);border-bottom-color:var(--c-accent)}
.ds-seg{display:inline-flex;background:var(--c-surface-2);border:1px solid var(--c-line);border-radius:9px;padding:3px}
.ds-seg > button{border:none;background:none;color:var(--c-txt-2);padding:5px 12px;border-radius:6px;cursor:pointer;font:var(--fs-13) var(--font)}
.ds-seg > button.is-active{background:var(--c-surface);color:var(--c-txt);box-shadow:var(--sh-1)}

/* ---- tooltip (CSS-only) ---- */
.ds-tip{position:relative}
.ds-tip::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 7px);left:50%;transform:translateX(-50%);
  background:var(--c-surface-2);border:1px solid var(--c-line-2);color:var(--c-txt);border-radius:8px;padding:6px 10px;
  font-size:var(--fs-12);white-space:nowrap;box-shadow:var(--sh-2);opacity:0;pointer-events:none;transition:opacity var(--t)}
.ds-tip:hover::after,.ds-tip:focus-visible::after{opacity:1}

/* ---- skeleton (loading) ---- */
.ds-skel{background:linear-gradient(90deg,var(--c-surface-2),var(--c-surface-hover),var(--c-surface-2));
  background-size:200% 100%;border-radius:6px;animation:ds-shimmer 1.3s linear infinite;min-height:14px}
@keyframes ds-shimmer{from{background-position:200% 0}to{background-position:-200% 0}}

/* ---- toast ---- */
.ds-toast{background:var(--c-surface-2);border:1px solid var(--c-line-2);border-radius:11px;padding:11px 17px;font-size:var(--fs-13);box-shadow:var(--sh-pop)}

/* ---- lightbox (click an image to enlarge, click again / Esc to dismiss) ----
   Mark any <img> with data-ds-lightbox; wire with the ~15-line snippet in the
   styleguide (builds one .ds-lightbox overlay, toggles .open). Scrim derives
   from --c-bg so it follows the active theme. */
[data-ds-lightbox]{cursor:zoom-in}
.ds-lightbox{position:fixed;inset:0;z-index:70;display:flex;align-items:center;justify-content:center;padding:var(--sp-8);
  background:color-mix(in srgb,var(--c-bg) 84%,transparent);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  cursor:zoom-out;opacity:0;visibility:hidden;transition:opacity var(--d-3) var(--e-exit),visibility 0s var(--d-3)}
.ds-lightbox.open{opacity:1;visibility:visible;transition:opacity var(--d-3) var(--e-standard)}
.ds-lightbox img{max-width:100%;max-height:100%;width:auto;height:auto;border:1px solid var(--c-line);border-radius:var(--r-lg);
  background:var(--c-surface);box-shadow:var(--sh-pop);transform:scale(.965);transition:transform var(--d-3) var(--e-entrance)}
.ds-lightbox.open img{transform:none}
@media (prefers-reduced-motion:reduce){.ds-lightbox,.ds-lightbox img{transition:none}}
}
