/* ==========================================================================
   AmPuH SEO Intelligence - Canonical Token Layer  v0.31.0
   --------------------------------------------------------------------------
   Single source of truth for design tokens.

   LOAD ORDER CONTRACT: this stylesheet must be the LAST stylesheet in <head>.
   It only declares custom properties plus accessibility guards. It contains
   no layout selectors, so it cannot move, resize, or reflow existing markup.
   Loading it last lets it reconcile the 33 duplicated :root blocks that had
   drifted into 6 different values of --pine, 5 of --warn, and 3 of --paper.

   Every foreground token below is verified against WCAG 2.2 AA (>= 4.5:1)
   on --paper, --surface and --soft. --lime is an ACCENT FILL ONLY: it fails
   as text (1.56:1) and must always carry --ink or --pine-dark on top.

   NOT unified here, by design: --surface and page-local aliases whose meaning
   genuinely diverges between modules (app.css and auth.css use --surface as a
   92% tint, everywhere else it is a ~99% card). Forcing those would collapse
   card/background separation on the landing and authentication surfaces.
   ========================================================================== */

:root {
  /* ---- Brand ramp ---------------------------------------------------- */
  --ds-pine:            oklch(37% .105 155);
  --ds-pine-hover:      oklch(31.5% .095 156);
  --ds-pine-dark:       oklch(25.5% .075 157);
  --ds-pine-tint:       oklch(94.8% .025 155);
  --ds-lime:            oklch(83% .145 116);
  --ds-lime-soft:       oklch(92.5% .075 116);

  /* ---- Neutrals ------------------------------------------------------ */
  --ds-bg:              oklch(96.7% .012 96);
  --ds-surface:         oklch(99.7% .003 96);
  --ds-surface-raised:  oklch(100% 0 0);
  --ds-surface-sunken:  oklch(93.2% .016 112);
  --ds-border:          oklch(87% .015 126);
  --ds-border-strong:   oklch(57% .028 150);
  --ds-text:            oklch(21.5% .030 151);
  --ds-text-muted:      oklch(45% .028 148);

  /* ---- Semantic status ----------------------------------------------- */
  --ds-success:         oklch(45.5% .115 152);
  --ds-success-tint:    oklch(94% .045 152);
  --ds-warning:         oklch(52.5% .110 72);
  --ds-warning-tint:    oklch(94.5% .050 82);
  --ds-danger:          oklch(47.5% .155 28);
  --ds-danger-tint:     oklch(94.5% .045 28);
  --ds-info:            oklch(45.5% .105 242);
  --ds-info-tint:       oklch(94.5% .035 242);
  --ds-neutral:         oklch(47.5% .026 148);
  --ds-neutral-tint:    oklch(93.5% .015 112);

  /* ---- Radius -------------------------------------------------------- */
  --ds-radius-sm: 8px;
  --ds-radius-md: 12px;
  --ds-radius-lg: 16px;
  --ds-radius-xl: 22px;
  --ds-radius-pill: 999px;

  /* ---- Elevation (restrained: never more than 3 levels) -------------- */
  --ds-shadow-sm: 0 1px 2px oklch(25% .05 155 / .05), 0 1px 8px oklch(25% .05 155 / .025);
  --ds-shadow-md: 0 2px 5px oklch(25% .05 155 / .05), 0 12px 28px oklch(25% .05 155 / .07);
  --ds-shadow-lg: 0 6px 14px oklch(25% .05 155 / .05), 0 24px 55px oklch(25% .05 155 / .10);

  /* ---- Spacing (4px base) -------------------------------------------- */
  --ds-space-1: 4px;
  --ds-space-2: 8px;
  --ds-space-3: 12px;
  --ds-space-4: 16px;
  --ds-space-5: 20px;
  --ds-space-6: 24px;
  --ds-space-8: 32px;
  --ds-space-10: 40px;
  --ds-space-12: 48px;
  --ds-space-16: 64px;

  /* ---- Type scale ---------------------------------------------------- */
  --ds-font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --ds-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  /* ==========================================================================================
     v0.92.0. THE 11px STEP IS GONE, AND ITS NAME WENT WITH IT.

     The scale used to open 11 / 12 / 13, three steps inside two pixels. Nobody can apply a 1px
     distinction deliberately, and the usage proved it: --ds-font-size-2xs had been reached for 131
     times for everything from an uppercase eyebrow to a sentence a customer reads. A token that
     cannot be chosen on purpose is not a scale step, it is a coin toss with a name.

     So the floor is 12px and 2xs is DELETED rather than redefined. Deleted, because redefining it to
     .75rem would leave two tokens with one value and 131 inline fallbacks still reading .6875rem: the
     fallback would then contradict the token it backs up, which is the drift this codebase spends its
     comments preventing. Every call site moved to --ds-font-size-xs, fallback included.

     WHAT --ds-font-size-preview IS FOR, AND WHY IT IS NOT A SCALE STEP. The free tools draw what
     Google, WhatsApp and Facebook will actually show. Those products set their own type sizes, and a
     preview rendered at OUR comfortable size would be a prettier lie about what the visitor sees -
     the same argument the SERP block already makes for quoting Google's link blue instead of our pine.
     Five rules use it. It is named for its reason so it cannot be mistaken for the bottom of the scale
     and quietly reused for our own chrome.
     ========================================================================================== */
  --ds-font-size-xs:  .75rem;
  --ds-font-size-preview: .6875rem;
  --ds-font-size-sm:  .8125rem;
  --ds-font-size-md:  .9375rem;
  --ds-font-size-lg:  1.0625rem;
  --ds-font-size-xl:  1.25rem;
  --ds-font-size-2xl: 1.5rem;
  --ds-font-size-3xl: 1.875rem;
  --ds-font-size-display: clamp(1.75rem, 2.4vw, 2.375rem);
  --ds-font-size-metric:  clamp(1.5rem, 2.2vw, 2rem);
  --ds-leading-tight: 1.18;
  --ds-leading-snug: 1.35;
  --ds-leading-normal: 1.55;
  --ds-tracking-label: .08em;

  /* ---- Motion -------------------------------------------------------- */
  --ds-ease: cubic-bezier(.16, 1, .3, 1);
  --ds-ease-out: cubic-bezier(.22, .61, .36, 1);
  --ds-duration: 160ms;

  /* ---- Layout -------------------------------------------------------- */
  --ds-shell-max: 1440px;
  --ds-gutter: clamp(16px, 3vw, 40px);
  --ds-touch: 44px;
  --ds-focus-ring: 3px;

  /* ======================================================================
     LEGACY ALIAS RECONCILIATION
     33 stylesheets already consume these names. Re-declaring them here
     harmonises all of them at once with zero selector edits and zero
     !important. Values are the AA-verified canonical ones above.
     ====================================================================== */
  --pine:      var(--ds-pine);
  --pine-dark: var(--ds-pine-dark);
  /* v0.31.3 CORRECTION: --deep was aliased to --ds-pine-dark in v0.31.0.
     Every stylesheet that declares --deep locally defines it as a pale tint
     (91-92% lightness) and uses it only as a background. Aliasing it to a
     29% near-black inverted 24 panel backgrounds on Google Cloud and Google
     API, leaving dark ink on a dark surface. Mapped to the sunken surface,
     which matches the intended tint. See PATCH-v0.31.3 section 1. */
  --deep:      var(--ds-surface-sunken);
  --lime:      var(--ds-lime);
  --lime-soft: var(--ds-lime-soft);
  --ink:       var(--ds-text);
  --muted:     var(--ds-text-muted);
  --line:      var(--ds-border);
  --line-strong: var(--ds-border-strong);
  --paper:     var(--ds-bg);
  --soft:      var(--ds-surface-sunken);
  --bad:       var(--ds-danger);
  --warn:      var(--ds-warning);
  --warning:   var(--ds-warning);
  --good:      var(--ds-success);
  --info:      var(--ds-info);
  --ease:      var(--ds-ease);

  /* Navigation aliases consumed by enterprise-navigation.css */
  --nav-pine:  var(--ds-pine-dark);
  --nav-lime:  var(--ds-lime);
  --nav-ink:   var(--ds-text);
  --nav-muted: var(--ds-text-muted);
  --nav-line:  var(--ds-border);
  --nav-paper: var(--ds-bg);
  --nav-soft:  var(--ds-surface-sunken);
  --nav-ease:  var(--ds-ease);

  /* Feature-registry aliases consumed by superadmin.css */
  --fr-ink:       var(--ds-text);
  --fr-muted:     var(--ds-text-muted);
  --fr-line:      var(--ds-border);
  --fr-line-soft: var(--ds-border);
  --fr-paper:     var(--ds-bg);
  --fr-soft:      var(--ds-surface-sunken);

  /* Responsive-system aliases */
  --rs-gutter: var(--ds-gutter);
  --rs-touch:  var(--ds-touch);
  --rs-ease:   var(--ds-ease);
}

/* ==========================================================================
   ACCESSIBILITY GUARDS
   Applied globally because they were previously inconsistent: 17 of 56
   stylesheets shipped no :focus-visible rule at all, and only 11 honoured
   reduced-motion.
   ========================================================================== */

:where(a, button, summary, [role="button"], [role="tab"], input, select, textarea, [tabindex]):focus-visible {
  outline: var(--ds-focus-ring) solid var(--ds-pine);
  outline-offset: 2px;
  border-radius: var(--ds-radius-sm);
}

::selection {
  background: var(--ds-lime-soft);
  color: var(--ds-pine-dark);
}

/* Skip link: keyboard entry point for every authenticated surface. */
.ds-skip-link {
  position: absolute;
  left: var(--ds-space-4);
  top: var(--ds-space-2);
  z-index: 100;
  padding: var(--ds-space-3) var(--ds-space-5);
  border-radius: var(--ds-radius-md);
  background: var(--ds-pine-dark);
  color: oklch(100% 0 0);
  font: 700 var(--ds-font-size-sm) / 1 var(--ds-font-sans);
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--ds-duration) var(--ds-ease);
}
.ds-skip-link:focus-visible { transform: translateY(0); }

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

@media (forced-colors: active) {
  .ds-badge,
  .ds-btn,
  .ds-card { border: 1px solid CanvasText; }
}

/* ==========================================================================
   GLOBAL BASELINE  (added v0.31.15)
   --------------------------------------------------------------------------
   THE SINGLE SOURCE OF TRUTH for rules that must apply to every surface.

   WHY IT MOVED HERE. These rules used to live in enterprise-interface.css,
   scoped to body:has(> header.enterprise-app-header). public_html/index.php
   injects that stylesheet only into pages whose header contains a /logout form,
   so four surfaces never received any of it:

       /               home.php
       /login          login.php
       /register       register.php
       /verify-email   verify-status.php

   That gap produced two shipped defects: a 117px h1 on the landing page
   (v0.31.7) and a 104px h1 on the authentication pages (v0.31.6). Both were
   patched locally. This removes the cause instead: ampuh-tokens.css is loaded by
   all 32 templates, in normal cascade order.

   The same baseline existed a third time in responsive-system.css. Three copies
   of one idea, each drifting. Both duplicates are removed in this patch.

   ZERO SPECIFICITY IS DELIBERATE. Everything below is wrapped in :where(), which
   contributes nothing to specificity, so ANY page rule overrides it without
   needing !important. That is the opposite of how enterprise-interface.css
   behaves, and it is why these rules are safe to apply globally: they are a
   floor, not a ceiling.
   ========================================================================== */

/* ---- Box model ---------------------------------------------------------- */
:where(*, *::before, *::after){box-sizing:border-box}

/* ---- Page frame --------------------------------------------------------- */
:where(html){-webkit-text-size-adjust:100%;text-size-adjust:100%}
:where(body){min-width:320px;overflow-x:hidden}
/* ==========================================================================================
   v1.6.0. THE TYPEFACE IS PART OF THE FLOOR, AND ITS ABSENCE WAS SHIPPING A SERIF.

   This layer set body colour, letter-spacing and the ambient background, and never once set
   font-family. Twenty-nine of the thirty-five page stylesheets declare `body{font: ... var(
   --ds-font-sans)}` of their own, which is why the omission stayed invisible for so long: the
   pages that would have exposed it are the newest ones. Eleven templates link no stylesheet
   that declares it - the five account-family pages (/billing/, /billing-review/, /profile/,
   /two-factor/, /audit-schedule/), the nineteen public /tools/ pages through free-tools.min.css,
   /preview/, /legal/, /migration-handoff/ and /page-source-audit/ - and every one of them was
   rendering its body copy, help text and table captions in whatever serif the browser defaults
   to, beside headings, badges and buttons that set the sans face explicitly.

   That is what "it does not look premium" was. Not the spacing and not the colour: a paid
   pricing page half-set in Times New Roman, on the surfaces we most recently built and on the
   only pages a stranger can reach without an account.

   WHY HERE AND NOT IN EACH SHEET. A typeface is true of every authenticated page and every
   public one, which is the stated test for this file. Adding it to five sheets would leave the
   next new page with the same defect and no way to notice it.

   WHY :where() AND NOT A BARE body RULE. Zero specificity. This file is the LAST stylesheet
   every template links, so a bare `body{font-family}` here would beat all twenty-nine sheets
   that set their own - including report-print.css and auth.css, which are entitled to their own
   typography. As a floor it applies only where nothing else spoke.
   ========================================================================================== */
:where(body){font-family:var(--ds-font-sans,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif)}
/* Grid and flex children must be allowed to shrink below their content width,
   or one long URL forces a horizontal scrollbar on the whole page. */
:where(main){min-width:0}
:where(main)>*{min-width:0}

/* ---- Text that must never overflow its container ----------------------- */
:where(h1,h2,h3,h4){overflow-wrap:anywhere;text-wrap:balance}
:where(p,li,dd,td){overflow-wrap:anywhere;text-wrap:pretty}
:where(code,pre,a){overflow-wrap:anywhere}
:where(code){max-width:100%;word-break:break-word}

/* ---- Media ------------------------------------------------------------- */
:where(img,svg,video,canvas){max-width:100%;height:auto}

/* ---- Form controls ----------------------------------------------------- */
:where(input,select,textarea,button){font-family:inherit}
/* A 16px minimum stops iOS Safari zooming the viewport on focus. Checkboxes and
   radios are excluded because the value would inflate their box. */
:where(input:not([type=checkbox]):not([type=radio]),select,textarea){font-size:1rem;line-height:1.4}
/* WCAG 2.5.8 target size. white-space:normal lets a long label wrap instead of
   forcing the control wider than its container. */
:where(button,summary,[role=button],input[type=button],input[type=submit],.primary,.setup-link){min-height:var(--ds-touch,44px);line-height:1.2;white-space:normal}
:where(button,a,input,summary){touch-action:manipulation}
:where(:focus-visible){scroll-margin:96px}

/* ---- max-width clamps, and the containing-block hazard ----------------- */
/* READ THIS BEFORE ADDING ANOTHER max-width HERE.

   For an absolutely or fixed positioned element a percentage max-width resolves
   against the padding box of its CONTAINING BLOCK, not the viewport. In v0.31.14
   `form{max-width:100%}` in the injected layer collapsed two popover panels to
   about 135px, because their containing block was a position:relative wrapper
   only as wide as the summary button. The submit button ended up far enough down
   the column to read as missing.

   Two defences now exist:
     1. these clamps are :where(), so any page rule overrides them
     2. .is-popover opts out entirely, and every positioned panel should carry it

   The three positioned panels that exist today are fixed per instance in
   v0.31.14; new ones should use the class. */
:where(form:not(.is-popover),table,.notice){max-width:100%}
/* Controls are never the positioned panel, so no opt-out is needed here.
   Writing :not() OUTSIDE :where() would have scored this (0,1,0), making it
   harder to override than a plain page rule at (0,0,1). Caught in review. */
:where(input,select,textarea,button){max-width:100%}
/* Not :where(): this must beat the clamps above. */
.is-popover{max-width:none}

/* ==========================================================================
   AUTHENTICATED APPLICATION SHELL          added v0.31.34, step 4 of 4
   --------------------------------------------------------------------------
   These rules used to live in public_html/assets/css/enterprise-interface.css,
   a stylesheet injected by public_html/index.php AFTER every page stylesheet.
   That file is deleted in this release and its link tag is removed from
   index.php. This is where the last of it lands.

   WHY THE SCOPE IS UNCHANGED. body:has(> header.enterprise-app-header) is not
   legacy baggage: index.php only rewrites the page header into
   header.enterprise-app-header when the template ships a <header> containing a
   /logout form. 26 of the 32 templates qualify. The other six (home, login,
   register, verify-status, audit-readiness, report-print) deliberately own their
   own typography, and a landing hero or a print artifact must not be forced into
   the application heading scale. An unscoped rule here would shrink the landing
   page h1 and reflow every printed report.

   WHY NO !important. In the injected file every one of these carried it, because
   an injected stylesheet cannot rely on source order. It does not need to now:
   the selector scores (0,1,3), no page stylesheet declares font-size, width or
   line-height on these elements at two classes or more (verified across all 35
   sheets), and ampuh-tokens.css is the last stylesheet each template links, so
   equal-specificity rules also lose to it. 94 !important declarations left the
   codebase with that file.

   ON ADDING TO THIS BLOCK. Only put something here if it is true of every
   authenticated page. Anything that is true of one page belongs in that page's
   stylesheet. That confusion is exactly what made the deleted file grow to 134
   !important declarations and start restyling unrelated components that happened
   to share a class name.
   ========================================================================== */
body:has(> header.enterprise-app-header){
  font-size:16px;
  line-height:1.5;
  text-rendering:optimizeLegibility;
  -webkit-font-smoothing:antialiased;
  font-optical-sizing:auto;
}

/* Shell width. The gutter widens as the viewport narrows so the reading column
   never touches the edge of a phone screen. */
body:has(> header.enterprise-app-header) main,
body:has(> header.enterprise-app-header) footer{max-width:1440px;min-width:0}
/* The automatic minimum size of a grid or flex item is its content, which is how
   one long unbroken token blows out a whole page. This is the net that catches
   it everywhere, so no page sheet has to remember. */
body:has(> header.enterprise-app-header) main *,
body:has(> header.enterprise-app-header) footer *{min-width:0}

/* Heading scale. One scale for 26 surfaces. Page stylesheets are free to set
   colour, weight, margin and letter-spacing; size is decided here. */
body:has(> header.enterprise-app-header) h1{font-size:clamp(1.75rem,2.4vw,2.375rem);line-height:1.18;letter-spacing:-.02em}
body:has(> header.enterprise-app-header) h2{font-size:clamp(1.125rem,1.6vw,1.375rem);line-height:1.3;letter-spacing:-.012em}
body:has(> header.enterprise-app-header) h3{font-size:clamp(1rem,1.2vw,1.125rem);line-height:1.35}

@media (max-width:1100px){
  body:has(> header.enterprise-app-header) main{width:min(100% - 40px,1440px);padding-top:36px}
}
@media (max-width:820px){
  body:has(> header.enterprise-app-header) main{width:min(100% - 32px,1440px);padding:32px 0 56px}
  body:has(> header.enterprise-app-header) h1{font-size:clamp(1.625rem,4.2vw,2rem)}
}
@media (max-width:600px){
  body:has(> header.enterprise-app-header) main{width:calc(100% - 24px);padding:24px 0 44px}
  body:has(> header.enterprise-app-header) footer{width:calc(100% - 24px)}
  body:has(> header.enterprise-app-header) h1{max-width:none;font-size:clamp(1.5rem,6vw,1.875rem);line-height:1.2}
  body:has(> header.enterprise-app-header) h2{font-size:1.1875rem}
  body:has(> header.enterprise-app-header) h3{font-size:1.0625rem}
  /* WCAG 2.5.8 gives 24px; the base token gives 44px; touch surfaces on a phone
     get 48px. This rule was silently dead from v0.31.27 to v0.31.32 because a
     trailing comma left it without a declaration block. */
  body:has(> header.enterprise-app-header) :is(button,summary,.primary){min-height:48px}
}

/* ==========================================================================
   ENTERPRISE PREMIUM UI LAYER v0.64.0
   --------------------------------------------------------------------------
   Visual-only refinement. DOM, routes, form names, data contracts and JS hooks remain
   untouched. It lives at the end of the canonical token stylesheet so every surface receives
   the same visual language.

   v0.64.1 folded this layer's second :root into the canonical block above. One file with two
   :root blocks setting the same twenty variables is two sources of truth for --ds-pine, and it
   is the duplication the v0.63.3 and v0.63.4 work existed to remove. The values are unchanged.
   ========================================================================== */


html { background: var(--ds-bg); }
body {
  color: var(--ds-text);
  letter-spacing: -.005em;
}
/* v0.64.1. THE AMBIENT WASH IS SCREEN-ONLY, and this has to be a media query rather than a
   cascade accident. report-print.css carries @media print { body { background:#fff;
   print-color-adjust:exact } }. This file loads AFTER it on the report page and the two body
   rules have equal specificity, so an unscoped background here won in print as well, while
   print-color-adjust:exact told the browser to ink it. Printed client reports came out with a
   lime and green wash on every page. */
@media screen {
  body {
    background:
      radial-gradient(circle at 88% -8%, oklch(91% .045 116 / .34), transparent 28rem),
      radial-gradient(circle at -8% 8%, oklch(92% .025 155 / .28), transparent 24rem),
      var(--ds-bg);
  }
}

/* Shared page chrome */
:where(header, .site-header, .product-header, .legal-header, .preview-header, .report-masthead) {
  border-bottom-color: color-mix(in oklab, var(--ds-border) 82%, transparent);
  box-shadow: 0 1px 0 oklch(100% 0 0 / .72), 0 8px 26px oklch(25% .05 155 / .035);
}

.brand img { filter: saturate(.96) contrast(1.02); }

/* Cards / panels */
:where(.ds-card, .ds-metric, .form-panel, .workflow-steps > li, .portfolio .project,
       .panel, .card, .tool-card, .report-card, .preview-card, .empty-state) {
  border-color: color-mix(in oklab, var(--ds-border) 92%, var(--ds-pine) 8%);
  background: color-mix(in oklab, var(--ds-surface) 96%, white 4%);
  box-shadow: var(--ds-shadow-sm);
}

:where(.ds-card, .form-panel, .panel, .card, .tool-card, .report-card, .preview-card):hover {
  border-color: color-mix(in oklab, var(--ds-border) 78%, var(--ds-pine) 22%);
  box-shadow: var(--ds-shadow-md);
}

.ds-card__head,
.ds-card__body,
.ds-card__foot { position: relative; }

.ds-card__head {
  background: linear-gradient(180deg, oklch(100% 0 0 / .62), transparent);
}

/* Typography hierarchy.
   v0.64.1. STEPS SNAPPED TO WEIGHTS THAT EXIST, was 760 / 720 / 680. --ds-font-sans is a system
   stack, and where the resolved face is not variable the browser snaps to the nearest weight it
   ships: 760, 720 and 680 all land on 700, collapsing this three-step hierarchy into one step,
   which is the opposite of the intent. 800 / 700 / 600 are steps every one of those faces has. */
:where(h1, h2, h3) {
  color: var(--ds-pine-dark);
  letter-spacing: -.025em;
}
:where(h1) { font-weight: 800; }
:where(h2) { font-weight: 700; }
:where(h3) { font-weight: 600; }
:where(.ds-eyebrow) { color: var(--ds-pine); font-weight: 700; letter-spacing: .105em; }

/* Controls: crisp enterprise affordance */
:where(.ds-input, input, select, textarea) {
  border-color: color-mix(in oklab, var(--ds-border) 88%, var(--ds-pine) 12%);
  background: oklch(100% 0 0 / .86);
  box-shadow: inset 0 1px 1px oklch(25% .05 155 / .025), 0 1px 0 oklch(100% 0 0 / .75);
  transition: border-color var(--ds-duration) var(--ds-ease), box-shadow var(--ds-duration) var(--ds-ease), transform var(--ds-duration) var(--ds-ease);
}
:where(.ds-input, input, select, textarea):hover {
  border-color: color-mix(in oklab, var(--ds-border) 68%, var(--ds-pine) 32%);
}
:where(.ds-input, input, select, textarea):focus {
  border-color: var(--ds-pine);
  box-shadow: 0 0 0 3px oklch(40% .092 155 / .13), 0 5px 16px oklch(25% .05 155 / .06);
}

:where(.ds-btn, button, [role="button"]) {
  transition: transform var(--ds-duration) var(--ds-ease), box-shadow var(--ds-duration) var(--ds-ease), background-color var(--ds-duration) var(--ds-ease), border-color var(--ds-duration) var(--ds-ease);
}
:where(.ds-btn, button):not(:disabled):hover {
  transform: translateY(-1px);
}
.ds-btn--primary {
  box-shadow: 0 1px 1px oklch(20% .05 155 / .16), 0 7px 18px oklch(30% .08 155 / .12);
}
.ds-btn--primary:hover { box-shadow: 0 2px 2px oklch(20% .05 155 / .18), 0 11px 24px oklch(30% .08 155 / .16); }

/* Metrics become executive KPI tiles without changing markup. */
.ds-metric {
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.ds-metric::after {
  content: "";
  position: absolute;
  width: 110px;
  height: 110px;
  right: -55px;
  top: -55px;
  border-radius: 50%;
  background: var(--ds-lime-soft);
  opacity: .42;
  z-index: -1;
}
.ds-metric__value { letter-spacing: -.045em; font-weight: 800; }
.ds-metric--accent { border-color: color-mix(in oklab, var(--ds-pine) 32%, var(--ds-border)); }

/* Tables: stronger scan rhythm, no structural changes. */
:where(.ds-table, table) { border-collapse: separate; border-spacing: 0; }
:where(.ds-table thead th, table thead th) {
  background: linear-gradient(180deg, var(--ds-pine-tint), color-mix(in oklab, var(--ds-pine-tint) 55%, var(--ds-surface)));
  color: var(--ds-pine-dark);
  font-weight: 700;
}
:where(.ds-table tbody tr, table tbody tr) { transition: background-color var(--ds-duration) var(--ds-ease); }
:where(.ds-table tbody tr:hover, table tbody tr:hover) { background: oklch(96% .018 155 / .42); }

/* Status badges / alerts: refined, less noisy. */
:where(.ds-badge, .badge) { box-shadow: inset 0 0 0 1px oklch(100% 0 0 / .42); font-weight: 700; }
:where(.ds-alert, .alert) { box-shadow: 0 1px 0 oklch(100% 0 0 / .72), var(--ds-shadow-sm); }

/* Navigation: premium command-center feel while retaining existing links.
   v0.64.1. SCOPED TO THE APP HEADER, was :where(..., nav). The blanket blurred nothing:
   breadcrumbs, in-page subnavs, provider rails and the stage rail are all <nav> and all sit on
   opaque surfaces, up to four per page, so there was no backdrop to filter. It was not free
   either: every backdrop-filter creates a compositing layer, a new stacking context, and a
   containing block for fixed-position descendants.
   -webkit- first, because iOS Safari still needs the prefix, and a translucent header is worth
   most on exactly that device. */
.enterprise-app-header {
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  backdrop-filter: blur(14px) saturate(120%);
}
:where(.enterprise-app-header a, .primary-nav a, nav a) {
  transition: color var(--ds-duration) var(--ds-ease), background-color var(--ds-duration) var(--ds-ease), transform var(--ds-duration) var(--ds-ease);
}
:where(.enterprise-app-header a:hover, .primary-nav a:hover, nav a:hover) {
  transform: translateY(-1px);
}

/* Dividers and disclosure surfaces */
:where(hr, .ds-divider) { border-color: var(--ds-border); opacity: .85; }
:where(details, .ds-disclose) { border-color: var(--ds-border); }

/* Mobile polish */
@media (max-width: 767px) {
  :where(.ds-card, .form-panel, .panel, .card, .tool-card, .report-card) { border-radius: var(--ds-radius-md); }
  :where(.ds-btn, button) { min-height: 44px; }
}
