@charset "UTF-8";
:root {
  --neutral-0: oklch(100% 0 0deg);
  --neutral-50: oklch(98.8% 0.002 260deg);
  --neutral-100: oklch(96.5% 0.003 260deg);
  --neutral-200: oklch(92% 0.004 260deg);
  --neutral-300: oklch(86% 0.005 260deg);
  --neutral-400: oklch(72% 0.008 260deg);
  --neutral-450: oklch(63% 0.009 260deg);
  --neutral-500: oklch(58% 0.01 260deg);
  --neutral-550: oklch(52% 0.011 260deg);
  --neutral-600: oklch(45% 0.012 260deg);
  --neutral-700: oklch(32% 0.013 260deg);
  --neutral-800: oklch(22% 0.012 260deg);
  --neutral-900: oklch(14% 0.01 260deg);
  --neutral-1000: oklch(8% 0.008 260deg);
  --success-50: oklch(97% 0.04 155deg);
  --success-100: oklch(92% 0.08 155deg);
  --success-500: oklch(65% 0.17 155deg);
  --success-700: oklch(48% 0.17 155deg);
  --success-900: oklch(28% 0.1 155deg);
  --warning-50: oklch(97% 0.04 85deg);
  --warning-100: oklch(92% 0.08 85deg);
  --warning-500: oklch(78% 0.16 85deg);
  --warning-700: oklch(48% 0.14 85deg);
  --warning-900: oklch(28% 0.08 85deg);
  --danger-50: oklch(97% 0.04 25deg);
  --danger-100: oklch(92% 0.08 25deg);
  --danger-500: oklch(58% 0.22 25deg);
  --danger-700: oklch(48% 0.2 25deg);
  --danger-900: oklch(28% 0.12 25deg);
  --info-50: oklch(97% 0.04 245deg);
  --info-100: oklch(92% 0.08 245deg);
  --info-500: oklch(65% 0.15 245deg);
  --info-700: oklch(48% 0.15 245deg);
  --info-900: oklch(28% 0.1 245deg);
  --success-ink: var(--success-700);
  --warning-ink: var(--warning-700);
  --danger-ink: var(--danger-700);
  --info-ink: var(--info-700);
  --fill-danger: var(--danger-500);
  --fill-danger-hover: oklch(48% 0.2 25deg);
  --text-on-danger: var(--neutral-0);
  --fill-success: var(--success-500);
  --text-on-success: var(--neutral-1000);
  --fill-warning: var(--warning-500);
  --text-on-warning: var(--neutral-1000);
  --fill-info: var(--info-500);
  --text-on-info: var(--neutral-1000);
  --accent-admin-50: oklch(97% 0.02 295deg);
  --accent-admin-100: oklch(93% 0.05 295deg);
  --accent-admin-200: oklch(86% 0.1 295deg);
  --accent-admin-400: oklch(72% 0.204 295deg);
  --accent-admin-500: oklch(58% 0.24 295deg);
  --accent-admin-600: oklch(54% 0.24 295deg);
  --accent-admin-700: oklch(46% 0.221 295deg);
  --accent-admin-900: oklch(28% 0.156 295deg);
  --accent-partner-50: oklch(97% 0.02 65deg);
  --accent-partner-100: oklch(93% 0.05 65deg);
  --accent-partner-200: oklch(86% 0.1 65deg);
  --accent-partner-400: oklch(66% 0.145 65deg);
  --accent-partner-500: oklch(56% 0.17 65deg);
  --accent-partner-600: oklch(48% 0.17 65deg);
  --accent-partner-700: oklch(40% 0.156 65deg);
  --accent-partner-900: oklch(28% 0.111 65deg);
  --accent-identity-50: oklch(97% 0.02 220deg);
  --accent-identity-100: oklch(93% 0.05 220deg);
  --accent-identity-200: oklch(86% 0.1 220deg);
  --accent-identity-400: oklch(63% 0.111 220deg);
  --accent-identity-500: oklch(53% 0.13 220deg);
  --accent-identity-600: oklch(45% 0.13 220deg);
  --accent-identity-700: oklch(37% 0.12 220deg);
  --accent-identity-900: oklch(28% 0.085 220deg);
  --accent-invoice-50: oklch(97% 0.02 160deg);
  --accent-invoice-100: oklch(93% 0.05 160deg);
  --accent-invoice-200: oklch(86% 0.1 160deg);
  --accent-invoice-400: oklch(62.5% 0.128 160deg);
  --accent-invoice-500: oklch(52.5% 0.15 160deg);
  --accent-invoice-600: oklch(44.5% 0.15 160deg);
  --accent-invoice-700: oklch(36.5% 0.138 160deg);
  --accent-invoice-900: oklch(28% 0.098 160deg);
  --accent-ninefive-50: oklch(97% 0.02 340deg);
  --accent-ninefive-100: oklch(93% 0.05 340deg);
  --accent-ninefive-200: oklch(86% 0.1 340deg);
  --accent-ninefive-400: oklch(68% 0.221 340deg);
  --accent-ninefive-500: oklch(58% 0.26 340deg);
  --accent-ninefive-600: oklch(50% 0.26 340deg);
  --accent-ninefive-700: oklch(42% 0.239 340deg);
  --accent-ninefive-900: oklch(28% 0.169 340deg);
  --gradient-border-subtle: linear-gradient(
    135deg,
    var(--accent-400),
    var(--accent-600)
  );
  --gradient-border-vivid: linear-gradient(
    135deg,
    var(--accent-admin-500),
    var(--accent-ninefive-500),
    var(--accent-identity-500)
  );
  --glass-surface: color-mix(in oklch, var(--surface-raised) 64%, transparent);
  --glass-blur: blur(20px) saturate(180%) brightness(1.06);
  --glass-border: 1px solid color-mix(in oklch, white 28%, transparent);
  --glass-shadow:
    0 16px 40px -12px color-mix(in oklch, var(--neutral-1000) 30%, transparent),
    0 2px 8px -4px color-mix(in oklch, var(--neutral-1000) 16%, transparent),
    inset 0 1px 0 0 color-mix(in oklch, white 65%, transparent),
    inset 0 0 0 1px color-mix(in oklch, white 8%, transparent);
  --glass-sheen: linear-gradient(150deg,
    color-mix(in oklch, white 38%, transparent) 0%,
    color-mix(in oklch, white 6%, transparent) 24%,
    transparent 48%);
  --overlay-scrim: color-mix(in oklch, var(--neutral-1000) 12%, transparent);
  --overlay-scrim-strong: color-mix(in oklch, var(--neutral-1000) 38%, transparent);
  --overlay-blur: blur(8px) saturate(120%);
  --glow-accent:
    0 0 0 3px color-mix(in oklch, var(--accent-500) 35%, transparent),
    0 0 24px color-mix(in oklch, var(--accent-500) 25%, transparent);
}

:root {
  --font-display: "Instrument Serif", ui-serif, Georgia, serif;
  --font-ui: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --text-3xs: 0.625rem; /* 10px */
  --text-2xs: 0.6875rem; /* 11px */
  --text-xs: 0.75rem; /* 12px */
  --text-sm: 0.8125rem; /* 13px */
  --text-base: 0.9375rem; /* 15px — default body */
  --text-md: 1rem; /* 16px */
  --text-lg: 1.125rem; /* 18px */
  --text-xl: 1.375rem; /* 22px */
  --text-2xl: 1.75rem; /* 28px */
  --text-3xl: 2.25rem; /* 36px */
  --text-4xl: 2.875rem; /* 46px */
  --text-5xl: 3.75rem; /* 60px */
  --text-6xl: 4.75rem; /* 76px */
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --leading-none: 1;
  --leading-tight: 1.15;
  --leading-snug: 1.3;
  --leading-normal: 1.5;
  --leading-relaxed: 1.65;
  --tracking-tight: -0.02em;
  --tracking-snug: -0.01em;
  --tracking-normal: 0;
  --tracking-wide: 0.02em;
  --tracking-widest: 0.08em;
  --icon-size-xs: 0.75rem; /* 12px */
  --icon-size-sm: 1rem; /* 16px */
  --icon-size-md: 1.25rem; /* 20px — default */
  --icon-size-lg: 1.5rem; /* 24px */
  --icon-size-xl: 2rem; /* 32px */
  --icon-stroke: 1.75;
}

:root {
  --type-display-xl-font: var(--font-display);
  --type-display-xl-size: var(--text-6xl);
  --type-display-xl-weight: var(--weight-regular);
  --type-display-xl-leading: var(--leading-none);
  --type-display-xl-tracking: var(--tracking-tight);
  --type-display-xl-transform: none;
  --type-display-xl-variant-numeric: normal;
  --type-display-lg-font: var(--font-display);
  --type-display-lg-size: var(--text-5xl);
  --type-display-lg-weight: var(--weight-regular);
  --type-display-lg-leading: var(--leading-tight);
  --type-display-lg-tracking: var(--tracking-tight);
  --type-display-lg-transform: none;
  --type-display-lg-variant-numeric: normal;
  --type-display-md-font: var(--font-display);
  --type-display-md-size: var(--text-4xl);
  --type-display-md-weight: var(--weight-regular);
  --type-display-md-leading: var(--leading-tight);
  --type-display-md-tracking: var(--tracking-snug);
  --type-display-md-transform: none;
  --type-display-md-variant-numeric: normal;
  --type-heading-xl-font: var(--font-ui);
  --type-heading-xl-size: var(--text-3xl);
  --type-heading-xl-weight: var(--weight-semibold);
  --type-heading-xl-leading: var(--leading-tight);
  --type-heading-xl-tracking: var(--tracking-snug);
  --type-heading-xl-transform: none;
  --type-heading-xl-variant-numeric: normal;
  --type-heading-lg-font: var(--font-ui);
  --type-heading-lg-size: var(--text-2xl);
  --type-heading-lg-weight: var(--weight-semibold);
  --type-heading-lg-leading: var(--leading-tight);
  --type-heading-lg-tracking: var(--tracking-snug);
  --type-heading-lg-transform: none;
  --type-heading-lg-variant-numeric: normal;
  --type-heading-md-font: var(--font-ui);
  --type-heading-md-size: var(--text-xl);
  --type-heading-md-weight: var(--weight-semibold);
  --type-heading-md-leading: var(--leading-snug);
  --type-heading-md-tracking: var(--tracking-normal);
  --type-heading-md-transform: none;
  --type-heading-md-variant-numeric: normal;
  --type-heading-sm-font: var(--font-ui);
  --type-heading-sm-size: var(--text-lg);
  --type-heading-sm-weight: var(--weight-semibold);
  --type-heading-sm-leading: var(--leading-snug);
  --type-heading-sm-tracking: var(--tracking-normal);
  --type-heading-sm-transform: none;
  --type-heading-sm-variant-numeric: normal;
  --type-body-lg-font: var(--font-ui);
  --type-body-lg-size: var(--text-md);
  --type-body-lg-weight: var(--weight-regular);
  --type-body-lg-leading: var(--leading-normal);
  --type-body-lg-tracking: var(--tracking-normal);
  --type-body-lg-transform: none;
  --type-body-lg-variant-numeric: normal;
  --type-body-font: var(--font-ui);
  --type-body-size: var(--text-base);
  --type-body-weight: var(--weight-regular);
  --type-body-leading: var(--leading-normal);
  --type-body-tracking: var(--tracking-normal);
  --type-body-transform: none;
  --type-body-variant-numeric: normal;
  --type-body-sm-font: var(--font-ui);
  --type-body-sm-size: var(--text-sm);
  --type-body-sm-weight: var(--weight-regular);
  --type-body-sm-leading: var(--leading-normal);
  --type-body-sm-tracking: var(--tracking-normal);
  --type-body-sm-transform: none;
  --type-body-sm-variant-numeric: normal;
  --type-ui-font: var(--font-ui);
  --type-ui-size: var(--text-sm);
  --type-ui-weight: var(--weight-medium);
  --type-ui-leading: var(--leading-snug);
  --type-ui-tracking: var(--tracking-normal);
  --type-ui-transform: none;
  --type-ui-variant-numeric: normal;
  --type-ui-sm-font: var(--font-ui);
  --type-ui-sm-size: var(--text-xs);
  --type-ui-sm-weight: var(--weight-medium);
  --type-ui-sm-leading: var(--leading-snug);
  --type-ui-sm-tracking: var(--tracking-normal);
  --type-ui-sm-transform: none;
  --type-ui-sm-variant-numeric: normal;
  --type-label-font: var(--font-ui);
  --type-label-size: var(--text-xs);
  --type-label-weight: var(--weight-medium);
  --type-label-leading: var(--leading-snug);
  --type-label-tracking: var(--tracking-wide);
  --type-label-transform: uppercase;
  --type-label-variant-numeric: normal;
  --type-label-sm-font: var(--font-ui);
  --type-label-sm-size: var(--text-3xs);
  --type-label-sm-weight: var(--weight-semibold);
  --type-label-sm-leading: var(--leading-none);
  --type-label-sm-tracking: var(--tracking-widest);
  --type-label-sm-transform: uppercase;
  --type-label-sm-variant-numeric: normal;
  --type-mono-font: var(--font-mono);
  --type-mono-size: var(--text-sm);
  --type-mono-weight: var(--weight-regular);
  --type-mono-leading: var(--leading-snug);
  --type-mono-tracking: var(--tracking-normal);
  --type-mono-transform: none;
  --type-mono-variant-numeric: tabular-nums;
  --type-mono-sm-font: var(--font-mono);
  --type-mono-sm-size: var(--text-xs);
  --type-mono-sm-weight: var(--weight-regular);
  --type-mono-sm-leading: var(--leading-snug);
  --type-mono-sm-tracking: var(--tracking-normal);
  --type-mono-sm-transform: none;
  --type-mono-sm-variant-numeric: tabular-nums;
}

:root {
  --type-heading-xl-size: clamp(var(--text-2xl), 5vw, var(--text-3xl));
  --type-heading-lg-size: clamp(var(--text-xl), 4vw, var(--text-2xl));
}

:root,
[data-density=comfortable] {
  --type-body-size: var(--text-base);
  --type-body-sm-size: var(--text-sm);
  --type-ui-size: var(--text-sm);
  --type-body-leading: var(--leading-normal);
}

[data-density=compact] {
  --type-body-size: var(--text-sm);
  --type-body-sm-size: var(--text-xs);
  --type-ui-size: var(--text-xs);
  --type-body-leading: var(--leading-snug);
}

:root {
  --space-0: 0;
  --space-px: 1px;
  --space-0-5: 0.125rem;
  --space-1: 0.25rem;
  --space-1-5: 0.375rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;
}

:root,
[data-density=comfortable] {
  /* Inset — padding within components */
  --space-inset-xs: var(--space-2); /* 8px  */
  --space-inset-sm: var(--space-3); /* 12px */
  --space-inset: var(--space-4); /* 16px — default */
  --space-inset-lg: var(--space-5); /* 20px */
  --space-inset-xl: var(--space-6); /* 24px */
  /* --- The 2xs rung (stack + inline) -----------------------------------
     2px is the most-written hardcoded number in the estate: 25 `gap: 2px`
     across the platform's app templates, 25 more inside this design system's
     own src/, and 49 further hardcoded Astra declarations whose value contains
     a 2px. That is not eyeballing — it is ONE shared idiom, the two-line
     name-over-detail stack inside a dense row, written identically everywhere,
     which is the signature of a real shape.

     Yet the raw `--space-0-5` (2px) was referenced in exactly two places in
     the whole system, both inside the [data-density="compact"] block below,
     which no page in the estate can currently reach. So 2px had no semantic
     name at all, and every sweep faced a false choice: double all ~50 gaps to
     `stack-xs` (4px) and change how dense rows look, or re-commit to the raw
     scale and keep spelling rhythm as measurement. This rung removes the
     choice. It is the bottom of the ladder, not a new step on the raw scale —
     the raw scale already had 2px and is not changed.

     REJECTED here, deliberately; do not reintroduce either:
       · a 6px semantic rung. When this was written `--space-1-5` (6px) was
         referenced 0 times in Astra. The W6 sweep since gave it ~10 uses, and
         they STRENGTHEN the rejection rather than reopening it: every one is
         RAW measurement — astra-badge's sm end-caps, the scrub-bubble chips in
         astra-audio/-slider/-video, astra-calendar's event bar, the nav row
         inset. Not one is rhythm between siblings, which is the only thing a
         semantic rung would be for. 6px is a control-geometry number, and it
         already has the right home.
       · re-basing `--space-inline-xs` from 4px to 6px. The ~9 near-6px values
         that suggest it (.3rem/.35rem/.4rem) are all one thing, the
         checkbox/radio-to-label gap — and astra-checkbox and astra-radio
         already own that gap at `--space-inline-sm` (8px). Re-basing would
         silently move astra-badge's internal gap, which is correctly 4px.
     -------------------------------------------------------------------- */
  /* Stack — vertical rhythm between siblings */
  --space-stack-2xs: var(--space-0-5); /* 2px — see the note above */
  --space-stack-xs: var(--space-1); /* 4px  */
  --space-stack-sm: var(--space-2); /* 8px  */
  --space-stack: var(--space-3); /* 12px — default */
  --space-stack-lg: var(--space-4); /* 16px */
  --space-stack-xl: var(--space-6); /* 24px */
  --space-stack-2xl: var(--space-8); /* 32px */
  /* Inline — horizontal rhythm between siblings */
  --space-inline-2xs: var(--space-0-5); /* 2px — see the note above */
  --space-inline-xs: var(--space-1); /* 4px  */
  --space-inline-sm: var(--space-2); /* 8px  */
  --space-inline: var(--space-3); /* 12px — default */
  --space-inline-lg: var(--space-4); /* 16px */
  /* Layout — major page-level rhythm */
  --space-layout-sm: var(--space-6); /* 24px */
  --space-layout: var(--space-8); /* 32px — default */
  --space-layout-lg: var(--space-12); /* 48px */
  --space-layout-xl: var(--space-16); /* 64px */
  /* Gutter — page edge padding. The three RUNGS; `--gutter` itself is
     derived from them by width in section 4 below. */
  --gutter-sm: var(--space-4); /* 16px — phone  */
  --gutter-md: var(--space-6); /* 24px — tablet / narrow desktop */
  --gutter-lg: var(--space-8); /* 32px — wide desktop */
}

[data-density=compact] {
  /* Inset */
  --space-inset-xs: var(--space-1); /* 8  → 4  */
  --space-inset-sm: var(--space-2); /* 12 → 8  */
  --space-inset: var(--space-3); /* 16 → 12 */
  --space-inset-lg: var(--space-4); /* 20 → 16 */
  --space-inset-xl: var(--space-5); /* 24 → 20 */
  /* Stack — 2xs steps to the 1px rung rather than colliding with xs, which
     is itself 2px here; the ladder stays strictly ordered in both densities
     and 2xs is never the wider of the two. */
  --space-stack-2xs: var(--space-px); /* 2  → 1  */
  --space-stack-xs: var(--space-0-5); /* 4  → 2  */
  --space-stack-sm: var(--space-1); /* 8  → 4  */
  --space-stack: var(--space-2); /* 12 → 8  */
  --space-stack-lg: var(--space-3); /* 16 → 12 */
  --space-stack-xl: var(--space-4); /* 24 → 16 */
  --space-stack-2xl: var(--space-6); /* 32 → 24 */
  /* Inline */
  --space-inline-2xs: var(--space-px); /* 2  → 1  */
  --space-inline-xs: var(--space-0-5); /* 4  → 2  */
  --space-inline-sm: var(--space-1); /* 8  → 4  */
  --space-inline: var(--space-2); /* 12 → 8  */
  --space-inline-lg: var(--space-3); /* 16 → 12 */
  /* Layout */
  --space-layout-sm: var(--space-4); /* 24 → 16 */
  --space-layout: var(--space-6); /* 32 → 24 */
  --space-layout-lg: var(--space-8); /* 48 → 32 */
  --space-layout-xl: var(--space-12); /* 64 → 48 */
  /* Gutter — the rungs move; the derived `--gutter` follows them for free */
  --gutter-sm: var(--space-3); /* 16 → 12 */
  --gutter-md: var(--space-4); /* 24 → 16 */
  --gutter-lg: var(--space-6); /* 32 → 24 */
}

:root,
[data-density] {
  --gutter: var(--gutter-sm);
}

@media (min-width: 768px) {
  :root,
  [data-density] {
    --gutter: var(--gutter-md);
  }
}
@media (min-width: 1280px) {
  :root,
  [data-density] {
    --gutter: var(--gutter-lg);
  }
}
:root {
  --radius-none: 0;
  --radius-xs: 0.125rem;
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-2xl: 1.25rem;
  --radius-3xl: 1.75rem;
  --radius-full: 9999px;
  --radius-control: var(--radius-md); /* buttons, inputs, selects   */
  --radius-card: var(--radius-xl); /* default cards              */
  --radius-surface: var(--radius-2xl); /* modals, large panels       */
  --radius-pill: var(--radius-full); /* badges, avatars, capsules  */
}

:root {
  --elevation-0: none;
  --elevation-1: 0 1px 2px rgba(0, 0, 0, 0.04);
  --elevation-2: 0 1px 2px rgba(0, 0, 0, 0.06),
                 0 2px 8px -2px rgba(0, 0, 0, 0.08);
  --elevation-3: 0 2px 4px rgba(0, 0, 0, 0.06),
                 0 8px 24px -4px rgba(0, 0, 0, 0.12);
  --elevation-4: 0 4px 8px rgba(0, 0, 0, 0.08),
                 0 16px 48px -8px rgba(0, 0, 0, 0.16);
  --elevation-5: 0 8px 16px rgba(0, 0, 0, 0.10),
                 0 32px 80px -12px rgba(0, 0, 0, 0.24);
  --elevation-pop:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    inset 0 -1px 0 rgba(0, 0, 0, 0.20),
    0 1px 2px rgba(0, 0, 0, 0.08),
    0 4px 12px -2px rgba(0, 0, 0, 0.12);
  --elevation-pop-hover:
    inset 0 1px 0 rgba(255, 255, 255, 0.15),
    inset 0 -1px 0 rgba(0, 0, 0, 0.25),
    0 2px 4px rgba(0, 0, 0, 0.10),
    0 8px 24px -4px rgba(0, 0, 0, 0.18);
  --elevation-inner-sm: inset 0 1px 2px rgba(0, 0, 0, 0.04);
  --elevation-inner: inset 0 2px 4px rgba(0, 0, 0, 0.06);
}

:root[data-theme=dark] {
  --elevation-1: 0 1px 2px rgba(0, 0, 0, 0.30);
  --elevation-2: 0 1px 2px rgba(0, 0, 0, 0.40),
                 0 2px 8px -2px rgba(0, 0, 0, 0.50);
  --elevation-3: 0 2px 4px rgba(0, 0, 0, 0.40),
                 0 8px 24px -4px rgba(0, 0, 0, 0.60);
  --elevation-4: 0 4px 8px rgba(0, 0, 0, 0.50),
                 0 16px 48px -8px rgba(0, 0, 0, 0.70);
  --elevation-5: 0 8px 16px rgba(0, 0, 0, 0.60),
                 0 32px 80px -12px rgba(0, 0, 0, 0.80);
  --elevation-pop:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    inset 0 -1px 0 rgba(0, 0, 0, 0.40),
    0 1px 2px rgba(0, 0, 0, 0.30),
    0 4px 12px -2px rgba(0, 0, 0, 0.40);
  --elevation-pop-hover:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 -1px 0 rgba(0, 0, 0, 0.50),
    0 2px 4px rgba(0, 0, 0, 0.40),
    0 8px 24px -4px rgba(0, 0, 0, 0.50);
  --elevation-inner-sm: inset 0 1px 2px rgba(0, 0, 0, 0.30);
  --elevation-inner: inset 0 2px 4px rgba(0, 0, 0, 0.40);
}

:root {
  --motion-instant: 0ms;
  --motion-fast: 100ms;
  --motion-default: 150ms;
  --motion-moderate: 220ms;
  --motion-slow: 380ms;
  --motion-deliberate: 600ms;
  --ease-linear: cubic-bezier(0, 0, 1, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in: cubic-bezier(0.7, 0, 0.84, 0);
  --ease-in-out: cubic-bezier(0.76, 0, 0.24, 1);
  --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --ease-anticipate: cubic-bezier(0.68, -0.4, 0.32, 1.4);
  --motion-hover: var(--motion-fast) var(--ease-out);
  --motion-focus: var(--motion-fast) var(--ease-out);
  --motion-press: var(--motion-instant);
  --motion-enter: var(--motion-moderate) var(--ease-spring);
  --motion-exit: var(--motion-default) var(--ease-in);
  --motion-transform: var(--motion-default) var(--ease-out);
  --motion-theme: var(--motion-slow) var(--ease-in-out);
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0ms;
    --motion-default: 0ms;
    --motion-moderate: 0ms;
    --motion-slow: 0ms;
    --motion-deliberate: 0ms;
  }
}
:root {
  --z-base: 0;
  --z-raised: 1;
  --z-sticky: 100;
  --z-dropdown: 200;
  --z-overlay: 300;
  --z-drawer: 400;
  --z-modal: 500;
  --z-popover: 600;
  --z-toast: 700;
  --z-tooltip: 800;
  --z-debug: 9999;
}

:root {
  --breakpoint-sm: 480px;
  --breakpoint-md: 768px;
  --breakpoint-lg: 1024px;
  --breakpoint-xl: 1280px;
  --breakpoint-2xl: 1536px;
}

:root,
:root[data-theme=light] {
  color-scheme: light;
  --surface-page: var(--neutral-50);
  --surface-raised: var(--neutral-0);
  --surface-sunken: var(--neutral-100);
  --surface-overlay: var(--neutral-0);
  --surface-selected: color-mix(in srgb, var(--accent-500) 8%, var(--surface-sunken));
  --border-selected: var(--accent-500);
  --border-subtle: var(--neutral-200);
  --border-default: var(--neutral-300);
  --border-strong: var(--neutral-400);
  --text-primary: var(--neutral-800);
  --text-secondary: var(--neutral-600);
  --text-tertiary: var(--neutral-550);
  --text-placeholder: var(--neutral-550);
  --text-disabled: var(--neutral-400);
  --text-inverse: var(--neutral-50);
  --scrollbar-thumb: color-mix(in oklch, var(--accent-500) 50%, transparent);
  --scrollbar-thumb-hover: color-mix(in oklch, var(--accent-600) 80%, transparent);
}

:root[data-theme=dark] {
  color-scheme: dark;
  --surface-page: var(--neutral-900);
  --surface-raised: var(--neutral-800);
  --surface-sunken: color-mix(in oklch, var(--neutral-800) 25%, var(--neutral-900));
  --surface-overlay: var(--neutral-800);
  --surface-selected: color-mix(in srgb, var(--accent-500) 16%,
                        color-mix(in srgb, var(--neutral-700) 55%, var(--surface-raised)));
  --border-selected: var(--accent-500);
  --border-subtle: color-mix(in oklch, white 8%, transparent);
  --border-default: color-mix(in oklch, white 14%, transparent);
  --border-strong: color-mix(in oklch, white 26%, transparent);
  --text-primary: var(--neutral-100);
  --text-secondary: var(--neutral-400);
  --text-tertiary: var(--neutral-450);
  --text-placeholder: var(--neutral-450);
  --text-disabled: var(--neutral-600);
  --text-inverse: var(--neutral-900);
  --scrollbar-thumb: color-mix(in oklch, var(--accent-400) 60%, transparent);
  --scrollbar-thumb-hover: color-mix(in oklch, var(--accent-400) 90%, transparent);
  --success-50: color-mix(in srgb, var(--success-500) 18%, var(--surface-raised));
  --success-100: color-mix(in srgb, var(--success-500) 28%, var(--surface-raised));
  --success-700: oklch(78% 0.15 155);
  --warning-50: color-mix(in srgb, var(--warning-500) 18%, var(--surface-raised));
  --warning-100: color-mix(in srgb, var(--warning-500) 28%, var(--surface-raised));
  --warning-700: oklch(80% 0.14 85);
  --danger-50: color-mix(in srgb, var(--danger-500) 18%, var(--surface-raised));
  --danger-100: color-mix(in srgb, var(--danger-500) 28%, var(--surface-raised));
  --danger-700: oklch(78% 0.16 25);
  --info-50: color-mix(in srgb, var(--info-500) 18%, var(--surface-raised));
  --info-100: color-mix(in srgb, var(--info-500) 28%, var(--surface-raised));
  --info-700: oklch(78% 0.13 245);
}

:where(:root), [data-group=admin] {
  --text-on-accent: var(--neutral-0);
  --accent-50: var(--accent-admin-50);
  --accent-100: var(--accent-admin-100);
  --accent-200: var(--accent-admin-200);
  --accent-400: var(--accent-admin-400);
  --accent-500: var(--accent-admin-500);
  --accent-600: var(--accent-admin-600);
  --accent-700: var(--accent-admin-700);
  --accent-900: var(--accent-admin-900);
  --fill-accent: var(--accent-admin-500);
  --fill-accent-shade: color-mix(in oklch, var(--accent-admin-500) 50%, var(--accent-admin-600));
  --fill-accent-hover: var(--accent-admin-600);
  --fill-accent-active: var(--accent-admin-700);
  --accent-ink-on-light: var(--accent-admin-600);
  --accent-ink-on-dark: var(--accent-admin-400);
  --accent-ink: var(--accent-ink-on-light);
  --accent-ink-on-tint: color-mix(in oklch, var(--accent-ink) 80%, var(--text-primary));
}

:where(:root[data-theme=dark]), :root[data-theme=dark] [data-group=admin], :root[data-theme=dark][data-group=admin] {
  --accent-ink: var(--accent-ink-on-dark);
}

[data-group=partner] {
  --text-on-accent: var(--neutral-0);
  --accent-50: var(--accent-partner-50);
  --accent-100: var(--accent-partner-100);
  --accent-200: var(--accent-partner-200);
  --accent-400: var(--accent-partner-400);
  --accent-500: var(--accent-partner-500);
  --accent-600: var(--accent-partner-600);
  --accent-700: var(--accent-partner-700);
  --accent-900: var(--accent-partner-900);
  --fill-accent: var(--accent-partner-500);
  --fill-accent-shade: color-mix(in oklch, var(--accent-partner-500) 50%, var(--accent-partner-600));
  --fill-accent-hover: var(--accent-partner-600);
  --fill-accent-active: var(--accent-partner-700);
  --accent-ink-on-light: var(--accent-partner-600);
  --accent-ink-on-dark: var(--accent-partner-400);
  --accent-ink: var(--accent-ink-on-light);
  --accent-ink-on-tint: color-mix(in oklch, var(--accent-ink) 80%, var(--text-primary));
}

:root[data-theme=dark] [data-group=partner], :root[data-theme=dark][data-group=partner] {
  --accent-ink: var(--accent-ink-on-dark);
}

[data-group=identity] {
  --text-on-accent: var(--neutral-0);
  --accent-50: var(--accent-identity-50);
  --accent-100: var(--accent-identity-100);
  --accent-200: var(--accent-identity-200);
  --accent-400: var(--accent-identity-400);
  --accent-500: var(--accent-identity-500);
  --accent-600: var(--accent-identity-600);
  --accent-700: var(--accent-identity-700);
  --accent-900: var(--accent-identity-900);
  --fill-accent: var(--accent-identity-500);
  --fill-accent-shade: color-mix(in oklch, var(--accent-identity-500) 50%, var(--accent-identity-600));
  --fill-accent-hover: var(--accent-identity-600);
  --fill-accent-active: var(--accent-identity-700);
  --accent-ink-on-light: var(--accent-identity-600);
  --accent-ink-on-dark: var(--accent-identity-400);
  --accent-ink: var(--accent-ink-on-light);
  --accent-ink-on-tint: color-mix(in oklch, var(--accent-ink) 80%, var(--text-primary));
}

:root[data-theme=dark] [data-group=identity], :root[data-theme=dark][data-group=identity] {
  --accent-ink: var(--accent-ink-on-dark);
}

[data-group=invoice] {
  --text-on-accent: var(--neutral-0);
  --accent-50: var(--accent-invoice-50);
  --accent-100: var(--accent-invoice-100);
  --accent-200: var(--accent-invoice-200);
  --accent-400: var(--accent-invoice-400);
  --accent-500: var(--accent-invoice-500);
  --accent-600: var(--accent-invoice-600);
  --accent-700: var(--accent-invoice-700);
  --accent-900: var(--accent-invoice-900);
  --fill-accent: var(--accent-invoice-500);
  --fill-accent-shade: color-mix(in oklch, var(--accent-invoice-500) 50%, var(--accent-invoice-600));
  --fill-accent-hover: var(--accent-invoice-600);
  --fill-accent-active: var(--accent-invoice-700);
  --accent-ink-on-light: var(--accent-invoice-600);
  --accent-ink-on-dark: var(--accent-invoice-400);
  --accent-ink: var(--accent-ink-on-light);
  --accent-ink-on-tint: color-mix(in oklch, var(--accent-ink) 80%, var(--text-primary));
}

:root[data-theme=dark] [data-group=invoice], :root[data-theme=dark][data-group=invoice] {
  --accent-ink: var(--accent-ink-on-dark);
}

[data-group=ninefive] {
  --text-on-accent: var(--neutral-0);
  --accent-50: var(--accent-ninefive-50);
  --accent-100: var(--accent-ninefive-100);
  --accent-200: var(--accent-ninefive-200);
  --accent-400: var(--accent-ninefive-400);
  --accent-500: var(--accent-ninefive-500);
  --accent-600: var(--accent-ninefive-600);
  --accent-700: var(--accent-ninefive-700);
  --accent-900: var(--accent-ninefive-900);
  --fill-accent: var(--accent-ninefive-500);
  --fill-accent-shade: color-mix(in oklch, var(--accent-ninefive-500) 50%, var(--accent-ninefive-600));
  --fill-accent-hover: var(--accent-ninefive-600);
  --fill-accent-active: var(--accent-ninefive-700);
  --accent-ink-on-light: var(--accent-ninefive-600);
  --accent-ink-on-dark: var(--accent-ninefive-400);
  --accent-ink: var(--accent-ink-on-light);
  --accent-ink-on-tint: color-mix(in oklch, var(--accent-ink) 80%, var(--text-primary));
}

:root[data-theme=dark] [data-group=ninefive], :root[data-theme=dark][data-group=ninefive] {
  --accent-ink: var(--accent-ink-on-dark);
}

@font-face {
  font-family: "Instrument Serif";
  src: url("fonts/instrument-serif-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Instrument Serif";
  src: url("fonts/instrument-serif-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-semibold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("fonts/inter-italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "JetBrains Mono";
  src: url("fonts/jetbrains-mono-medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
* {
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
  transition: scrollbar-color var(--motion-hover);
}

*:hover,
*:focus-within {
  scrollbar-color: var(--scrollbar-thumb) transparent;
}

*::-webkit-scrollbar {
  -webkit-appearance: none;
  appearance: none;
  width: 6px;
  height: 6px;
}

*::-webkit-scrollbar-track {
  background: transparent;
}

*::-webkit-scrollbar-thumb {
  background: transparent;
  border-radius: var(--radius-full);
  transition: background-color var(--motion-hover);
}

*:hover::-webkit-scrollbar-thumb,
*:focus-within::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb);
}

*::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-thumb-hover);
}

*::-webkit-scrollbar-corner {
  background: transparent;
}

astra-input,
astra-select,
astra-textarea,
astra-combobox,
astra-number-input,
astra-tag-input,
astra-otp-input,
astra-file-upload,
astra-media-picker {
  min-width: 0;
  max-width: 100%;
}

astra-button {
  max-width: 100%;
}

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

a {
  color: var(--accent-ink);
  font-weight: var(--weight-medium);
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

a:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

[hidden] {
  display: none !important;
}

html {
  font-size: 100%;
  font-family: var(--font-ui);
  font-feature-settings: "cv11", "ss01", "cv02", "cv03", "cv04";
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-family: var(--type-body-font);
  font-size: var(--type-body-size);
  font-weight: var(--type-body-weight);
  line-height: var(--type-body-leading);
  letter-spacing: var(--type-body-tracking);
  text-transform: var(--type-body-transform);
  font-variant-numeric: var(--type-body-variant-numeric);
  color: var(--text-primary);
  background: var(--surface-page);
  margin: 0;
}

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  color: var(--text-primary);
}

h1 {
  font-family: var(--type-heading-xl-font);
  font-size: var(--type-heading-xl-size);
  font-weight: var(--type-heading-xl-weight);
  line-height: var(--type-heading-xl-leading);
  letter-spacing: var(--type-heading-xl-tracking);
  text-transform: var(--type-heading-xl-transform);
  font-variant-numeric: var(--type-heading-xl-variant-numeric);
}

h2 {
  font-family: var(--type-heading-lg-font);
  font-size: var(--type-heading-lg-size);
  font-weight: var(--type-heading-lg-weight);
  line-height: var(--type-heading-lg-leading);
  letter-spacing: var(--type-heading-lg-tracking);
  text-transform: var(--type-heading-lg-transform);
  font-variant-numeric: var(--type-heading-lg-variant-numeric);
}

h3 {
  font-family: var(--type-heading-md-font);
  font-size: var(--type-heading-md-size);
  font-weight: var(--type-heading-md-weight);
  line-height: var(--type-heading-md-leading);
  letter-spacing: var(--type-heading-md-tracking);
  text-transform: var(--type-heading-md-transform);
  font-variant-numeric: var(--type-heading-md-variant-numeric);
}

h4 {
  font-family: var(--type-heading-sm-font);
  font-size: var(--type-heading-sm-size);
  font-weight: var(--type-heading-sm-weight);
  line-height: var(--type-heading-sm-leading);
  letter-spacing: var(--type-heading-sm-tracking);
  text-transform: var(--type-heading-sm-transform);
  font-variant-numeric: var(--type-heading-sm-variant-numeric);
}

h5 {
  font-family: var(--type-body-lg-font);
  font-size: var(--type-body-lg-size);
  font-weight: var(--type-body-lg-weight);
  line-height: var(--type-body-lg-leading);
  letter-spacing: var(--type-body-lg-tracking);
  text-transform: var(--type-body-lg-transform);
  font-variant-numeric: var(--type-body-lg-variant-numeric);
  font-weight: var(--weight-semibold);
}

h6 {
  font-family: var(--type-ui-font);
  font-size: var(--type-ui-size);
  font-weight: var(--type-ui-weight);
  line-height: var(--type-ui-leading);
  letter-spacing: var(--type-ui-tracking);
  text-transform: var(--type-ui-transform);
  font-variant-numeric: var(--type-ui-variant-numeric);
}

p {
  font-family: var(--type-body-font);
  font-size: var(--type-body-size);
  font-weight: var(--type-body-weight);
  line-height: var(--type-body-leading);
  letter-spacing: var(--type-body-tracking);
  text-transform: var(--type-body-transform);
  font-variant-numeric: var(--type-body-variant-numeric);
  margin: 0;
}

code, pre, kbd, samp {
  font-family: var(--type-mono-font);
  font-size: var(--type-mono-size);
  font-weight: var(--type-mono-weight);
  line-height: var(--type-mono-leading);
  letter-spacing: var(--type-mono-tracking);
  text-transform: var(--type-mono-transform);
  font-variant-numeric: var(--type-mono-variant-numeric);
}

em, i {
  font-style: italic;
}

strong, b {
  font-weight: var(--weight-semibold);
}

small {
  font-family: var(--type-body-sm-font);
  font-size: var(--type-body-sm-size);
  font-weight: var(--type-body-sm-weight);
  line-height: var(--type-body-sm-leading);
  letter-spacing: var(--type-body-sm-tracking);
  text-transform: var(--type-body-sm-transform);
  font-variant-numeric: var(--type-body-sm-variant-numeric);
  color: var(--text-secondary);
}

::selection {
  background: var(--accent-200);
  color: var(--text-primary);
}

.print-only {
  display: none;
}

@media print {
  :root,
  :root[data-theme=dark],
  :root[data-theme=light] {
    color-scheme: light;
    --surface-page: var(--neutral-0);
    --surface-raised: var(--neutral-0);
    --surface-sunken: var(--neutral-100);
    --surface-overlay: var(--neutral-0);
    --border-subtle: var(--neutral-200);
    --border-default: var(--neutral-300);
    --border-strong: var(--neutral-400);
    --text-primary: var(--neutral-900);
    --text-secondary: var(--neutral-700);
    --text-tertiary: var(--neutral-600);
    --text-placeholder: var(--neutral-500);
    --success-50: oklch(97% 0.04 155);
    --success-100: oklch(92% 0.08 155);
    --success-700: oklch(48% 0.17 155);
    --warning-50: oklch(97% 0.04 85);
    --warning-100: oklch(92% 0.08 85);
    --warning-700: oklch(48% 0.14 85);
    --danger-50: oklch(97% 0.04 25);
    --danger-100: oklch(92% 0.08 25);
    --danger-700: oklch(48% 0.20 25);
    --info-50: oklch(97% 0.04 245);
    --info-100: oklch(92% 0.08 245);
    --info-700: oklch(48% 0.15 245);
    --accent-ink: var(--accent-ink-on-light);
  }
  html, body {
    background: #fff !important;
    color: var(--neutral-900) !important;
    margin: 0 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  *, *::before, *::after {
    box-shadow: none !important;
    text-shadow: none !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .no-print,
  .screen-only,
  [data-print=hide] {
    display: none !important;
  }
  .print-only {
    display: revert !important;
  }
  h1, h2, h3, h4 {
    break-after: avoid;
  }
  img, svg {
    max-width: 100% !important;
  }
  .page-break-before {
    break-before: page;
  }
  .page-break-after {
    break-after: page;
  }
  .print-avoid-break {
    break-inside: avoid;
  }
}
@page {
  margin: 18mm;
}
.p-0 {
  padding: var(--space-0);
}

.px-0 {
  padding-inline: var(--space-0);
}

.py-0 {
  padding-block: var(--space-0);
}

.pt-0 {
  padding-block-start: var(--space-0);
}

.pr-0 {
  padding-inline-end: var(--space-0);
}

.pb-0 {
  padding-block-end: var(--space-0);
}

.pl-0 {
  padding-inline-start: var(--space-0);
}

.m-0 {
  margin: var(--space-0);
}

.mx-0 {
  margin-inline: var(--space-0);
}

.my-0 {
  margin-block: var(--space-0);
}

.mt-0 {
  margin-block-start: var(--space-0);
}

.mr-0 {
  margin-inline-end: var(--space-0);
}

.mb-0 {
  margin-block-end: var(--space-0);
}

.ml-0 {
  margin-inline-start: var(--space-0);
}

.gap-0 {
  gap: var(--space-0);
}

.gap-x-0 {
  column-gap: var(--space-0);
}

.gap-y-0 {
  row-gap: var(--space-0);
}

.p-px {
  padding: var(--space-px);
}

.px-px {
  padding-inline: var(--space-px);
}

.py-px {
  padding-block: var(--space-px);
}

.pt-px {
  padding-block-start: var(--space-px);
}

.pr-px {
  padding-inline-end: var(--space-px);
}

.pb-px {
  padding-block-end: var(--space-px);
}

.pl-px {
  padding-inline-start: var(--space-px);
}

.m-px {
  margin: var(--space-px);
}

.mx-px {
  margin-inline: var(--space-px);
}

.my-px {
  margin-block: var(--space-px);
}

.mt-px {
  margin-block-start: var(--space-px);
}

.mr-px {
  margin-inline-end: var(--space-px);
}

.mb-px {
  margin-block-end: var(--space-px);
}

.ml-px {
  margin-inline-start: var(--space-px);
}

.gap-px {
  gap: var(--space-px);
}

.gap-x-px {
  column-gap: var(--space-px);
}

.gap-y-px {
  row-gap: var(--space-px);
}

.p-0-5 {
  padding: var(--space-0-5);
}

.px-0-5 {
  padding-inline: var(--space-0-5);
}

.py-0-5 {
  padding-block: var(--space-0-5);
}

.pt-0-5 {
  padding-block-start: var(--space-0-5);
}

.pr-0-5 {
  padding-inline-end: var(--space-0-5);
}

.pb-0-5 {
  padding-block-end: var(--space-0-5);
}

.pl-0-5 {
  padding-inline-start: var(--space-0-5);
}

.m-0-5 {
  margin: var(--space-0-5);
}

.mx-0-5 {
  margin-inline: var(--space-0-5);
}

.my-0-5 {
  margin-block: var(--space-0-5);
}

.mt-0-5 {
  margin-block-start: var(--space-0-5);
}

.mr-0-5 {
  margin-inline-end: var(--space-0-5);
}

.mb-0-5 {
  margin-block-end: var(--space-0-5);
}

.ml-0-5 {
  margin-inline-start: var(--space-0-5);
}

.gap-0-5 {
  gap: var(--space-0-5);
}

.gap-x-0-5 {
  column-gap: var(--space-0-5);
}

.gap-y-0-5 {
  row-gap: var(--space-0-5);
}

.p-1 {
  padding: var(--space-1);
}

.px-1 {
  padding-inline: var(--space-1);
}

.py-1 {
  padding-block: var(--space-1);
}

.pt-1 {
  padding-block-start: var(--space-1);
}

.pr-1 {
  padding-inline-end: var(--space-1);
}

.pb-1 {
  padding-block-end: var(--space-1);
}

.pl-1 {
  padding-inline-start: var(--space-1);
}

.m-1 {
  margin: var(--space-1);
}

.mx-1 {
  margin-inline: var(--space-1);
}

.my-1 {
  margin-block: var(--space-1);
}

.mt-1 {
  margin-block-start: var(--space-1);
}

.mr-1 {
  margin-inline-end: var(--space-1);
}

.mb-1 {
  margin-block-end: var(--space-1);
}

.ml-1 {
  margin-inline-start: var(--space-1);
}

.gap-1 {
  gap: var(--space-1);
}

.gap-x-1 {
  column-gap: var(--space-1);
}

.gap-y-1 {
  row-gap: var(--space-1);
}

.p-1-5 {
  padding: var(--space-1-5);
}

.px-1-5 {
  padding-inline: var(--space-1-5);
}

.py-1-5 {
  padding-block: var(--space-1-5);
}

.pt-1-5 {
  padding-block-start: var(--space-1-5);
}

.pr-1-5 {
  padding-inline-end: var(--space-1-5);
}

.pb-1-5 {
  padding-block-end: var(--space-1-5);
}

.pl-1-5 {
  padding-inline-start: var(--space-1-5);
}

.m-1-5 {
  margin: var(--space-1-5);
}

.mx-1-5 {
  margin-inline: var(--space-1-5);
}

.my-1-5 {
  margin-block: var(--space-1-5);
}

.mt-1-5 {
  margin-block-start: var(--space-1-5);
}

.mr-1-5 {
  margin-inline-end: var(--space-1-5);
}

.mb-1-5 {
  margin-block-end: var(--space-1-5);
}

.ml-1-5 {
  margin-inline-start: var(--space-1-5);
}

.gap-1-5 {
  gap: var(--space-1-5);
}

.gap-x-1-5 {
  column-gap: var(--space-1-5);
}

.gap-y-1-5 {
  row-gap: var(--space-1-5);
}

.p-2 {
  padding: var(--space-2);
}

.px-2 {
  padding-inline: var(--space-2);
}

.py-2 {
  padding-block: var(--space-2);
}

.pt-2 {
  padding-block-start: var(--space-2);
}

.pr-2 {
  padding-inline-end: var(--space-2);
}

.pb-2 {
  padding-block-end: var(--space-2);
}

.pl-2 {
  padding-inline-start: var(--space-2);
}

.m-2 {
  margin: var(--space-2);
}

.mx-2 {
  margin-inline: var(--space-2);
}

.my-2 {
  margin-block: var(--space-2);
}

.mt-2 {
  margin-block-start: var(--space-2);
}

.mr-2 {
  margin-inline-end: var(--space-2);
}

.mb-2 {
  margin-block-end: var(--space-2);
}

.ml-2 {
  margin-inline-start: var(--space-2);
}

.gap-2 {
  gap: var(--space-2);
}

.gap-x-2 {
  column-gap: var(--space-2);
}

.gap-y-2 {
  row-gap: var(--space-2);
}

.p-3 {
  padding: var(--space-3);
}

.px-3 {
  padding-inline: var(--space-3);
}

.py-3 {
  padding-block: var(--space-3);
}

.pt-3 {
  padding-block-start: var(--space-3);
}

.pr-3 {
  padding-inline-end: var(--space-3);
}

.pb-3 {
  padding-block-end: var(--space-3);
}

.pl-3 {
  padding-inline-start: var(--space-3);
}

.m-3 {
  margin: var(--space-3);
}

.mx-3 {
  margin-inline: var(--space-3);
}

.my-3 {
  margin-block: var(--space-3);
}

.mt-3 {
  margin-block-start: var(--space-3);
}

.mr-3 {
  margin-inline-end: var(--space-3);
}

.mb-3 {
  margin-block-end: var(--space-3);
}

.ml-3 {
  margin-inline-start: var(--space-3);
}

.gap-3 {
  gap: var(--space-3);
}

.gap-x-3 {
  column-gap: var(--space-3);
}

.gap-y-3 {
  row-gap: var(--space-3);
}

.p-4 {
  padding: var(--space-4);
}

.px-4 {
  padding-inline: var(--space-4);
}

.py-4 {
  padding-block: var(--space-4);
}

.pt-4 {
  padding-block-start: var(--space-4);
}

.pr-4 {
  padding-inline-end: var(--space-4);
}

.pb-4 {
  padding-block-end: var(--space-4);
}

.pl-4 {
  padding-inline-start: var(--space-4);
}

.m-4 {
  margin: var(--space-4);
}

.mx-4 {
  margin-inline: var(--space-4);
}

.my-4 {
  margin-block: var(--space-4);
}

.mt-4 {
  margin-block-start: var(--space-4);
}

.mr-4 {
  margin-inline-end: var(--space-4);
}

.mb-4 {
  margin-block-end: var(--space-4);
}

.ml-4 {
  margin-inline-start: var(--space-4);
}

.gap-4 {
  gap: var(--space-4);
}

.gap-x-4 {
  column-gap: var(--space-4);
}

.gap-y-4 {
  row-gap: var(--space-4);
}

.p-5 {
  padding: var(--space-5);
}

.px-5 {
  padding-inline: var(--space-5);
}

.py-5 {
  padding-block: var(--space-5);
}

.pt-5 {
  padding-block-start: var(--space-5);
}

.pr-5 {
  padding-inline-end: var(--space-5);
}

.pb-5 {
  padding-block-end: var(--space-5);
}

.pl-5 {
  padding-inline-start: var(--space-5);
}

.m-5 {
  margin: var(--space-5);
}

.mx-5 {
  margin-inline: var(--space-5);
}

.my-5 {
  margin-block: var(--space-5);
}

.mt-5 {
  margin-block-start: var(--space-5);
}

.mr-5 {
  margin-inline-end: var(--space-5);
}

.mb-5 {
  margin-block-end: var(--space-5);
}

.ml-5 {
  margin-inline-start: var(--space-5);
}

.gap-5 {
  gap: var(--space-5);
}

.gap-x-5 {
  column-gap: var(--space-5);
}

.gap-y-5 {
  row-gap: var(--space-5);
}

.p-6 {
  padding: var(--space-6);
}

.px-6 {
  padding-inline: var(--space-6);
}

.py-6 {
  padding-block: var(--space-6);
}

.pt-6 {
  padding-block-start: var(--space-6);
}

.pr-6 {
  padding-inline-end: var(--space-6);
}

.pb-6 {
  padding-block-end: var(--space-6);
}

.pl-6 {
  padding-inline-start: var(--space-6);
}

.m-6 {
  margin: var(--space-6);
}

.mx-6 {
  margin-inline: var(--space-6);
}

.my-6 {
  margin-block: var(--space-6);
}

.mt-6 {
  margin-block-start: var(--space-6);
}

.mr-6 {
  margin-inline-end: var(--space-6);
}

.mb-6 {
  margin-block-end: var(--space-6);
}

.ml-6 {
  margin-inline-start: var(--space-6);
}

.gap-6 {
  gap: var(--space-6);
}

.gap-x-6 {
  column-gap: var(--space-6);
}

.gap-y-6 {
  row-gap: var(--space-6);
}

.p-8 {
  padding: var(--space-8);
}

.px-8 {
  padding-inline: var(--space-8);
}

.py-8 {
  padding-block: var(--space-8);
}

.pt-8 {
  padding-block-start: var(--space-8);
}

.pr-8 {
  padding-inline-end: var(--space-8);
}

.pb-8 {
  padding-block-end: var(--space-8);
}

.pl-8 {
  padding-inline-start: var(--space-8);
}

.m-8 {
  margin: var(--space-8);
}

.mx-8 {
  margin-inline: var(--space-8);
}

.my-8 {
  margin-block: var(--space-8);
}

.mt-8 {
  margin-block-start: var(--space-8);
}

.mr-8 {
  margin-inline-end: var(--space-8);
}

.mb-8 {
  margin-block-end: var(--space-8);
}

.ml-8 {
  margin-inline-start: var(--space-8);
}

.gap-8 {
  gap: var(--space-8);
}

.gap-x-8 {
  column-gap: var(--space-8);
}

.gap-y-8 {
  row-gap: var(--space-8);
}

.p-10 {
  padding: var(--space-10);
}

.px-10 {
  padding-inline: var(--space-10);
}

.py-10 {
  padding-block: var(--space-10);
}

.pt-10 {
  padding-block-start: var(--space-10);
}

.pr-10 {
  padding-inline-end: var(--space-10);
}

.pb-10 {
  padding-block-end: var(--space-10);
}

.pl-10 {
  padding-inline-start: var(--space-10);
}

.m-10 {
  margin: var(--space-10);
}

.mx-10 {
  margin-inline: var(--space-10);
}

.my-10 {
  margin-block: var(--space-10);
}

.mt-10 {
  margin-block-start: var(--space-10);
}

.mr-10 {
  margin-inline-end: var(--space-10);
}

.mb-10 {
  margin-block-end: var(--space-10);
}

.ml-10 {
  margin-inline-start: var(--space-10);
}

.gap-10 {
  gap: var(--space-10);
}

.gap-x-10 {
  column-gap: var(--space-10);
}

.gap-y-10 {
  row-gap: var(--space-10);
}

.p-12 {
  padding: var(--space-12);
}

.px-12 {
  padding-inline: var(--space-12);
}

.py-12 {
  padding-block: var(--space-12);
}

.pt-12 {
  padding-block-start: var(--space-12);
}

.pr-12 {
  padding-inline-end: var(--space-12);
}

.pb-12 {
  padding-block-end: var(--space-12);
}

.pl-12 {
  padding-inline-start: var(--space-12);
}

.m-12 {
  margin: var(--space-12);
}

.mx-12 {
  margin-inline: var(--space-12);
}

.my-12 {
  margin-block: var(--space-12);
}

.mt-12 {
  margin-block-start: var(--space-12);
}

.mr-12 {
  margin-inline-end: var(--space-12);
}

.mb-12 {
  margin-block-end: var(--space-12);
}

.ml-12 {
  margin-inline-start: var(--space-12);
}

.gap-12 {
  gap: var(--space-12);
}

.gap-x-12 {
  column-gap: var(--space-12);
}

.gap-y-12 {
  row-gap: var(--space-12);
}

.p-16 {
  padding: var(--space-16);
}

.px-16 {
  padding-inline: var(--space-16);
}

.py-16 {
  padding-block: var(--space-16);
}

.pt-16 {
  padding-block-start: var(--space-16);
}

.pr-16 {
  padding-inline-end: var(--space-16);
}

.pb-16 {
  padding-block-end: var(--space-16);
}

.pl-16 {
  padding-inline-start: var(--space-16);
}

.m-16 {
  margin: var(--space-16);
}

.mx-16 {
  margin-inline: var(--space-16);
}

.my-16 {
  margin-block: var(--space-16);
}

.mt-16 {
  margin-block-start: var(--space-16);
}

.mr-16 {
  margin-inline-end: var(--space-16);
}

.mb-16 {
  margin-block-end: var(--space-16);
}

.ml-16 {
  margin-inline-start: var(--space-16);
}

.gap-16 {
  gap: var(--space-16);
}

.gap-x-16 {
  column-gap: var(--space-16);
}

.gap-y-16 {
  row-gap: var(--space-16);
}

.p-20 {
  padding: var(--space-20);
}

.px-20 {
  padding-inline: var(--space-20);
}

.py-20 {
  padding-block: var(--space-20);
}

.pt-20 {
  padding-block-start: var(--space-20);
}

.pr-20 {
  padding-inline-end: var(--space-20);
}

.pb-20 {
  padding-block-end: var(--space-20);
}

.pl-20 {
  padding-inline-start: var(--space-20);
}

.m-20 {
  margin: var(--space-20);
}

.mx-20 {
  margin-inline: var(--space-20);
}

.my-20 {
  margin-block: var(--space-20);
}

.mt-20 {
  margin-block-start: var(--space-20);
}

.mr-20 {
  margin-inline-end: var(--space-20);
}

.mb-20 {
  margin-block-end: var(--space-20);
}

.ml-20 {
  margin-inline-start: var(--space-20);
}

.gap-20 {
  gap: var(--space-20);
}

.gap-x-20 {
  column-gap: var(--space-20);
}

.gap-y-20 {
  row-gap: var(--space-20);
}

.p-24 {
  padding: var(--space-24);
}

.px-24 {
  padding-inline: var(--space-24);
}

.py-24 {
  padding-block: var(--space-24);
}

.pt-24 {
  padding-block-start: var(--space-24);
}

.pr-24 {
  padding-inline-end: var(--space-24);
}

.pb-24 {
  padding-block-end: var(--space-24);
}

.pl-24 {
  padding-inline-start: var(--space-24);
}

.m-24 {
  margin: var(--space-24);
}

.mx-24 {
  margin-inline: var(--space-24);
}

.my-24 {
  margin-block: var(--space-24);
}

.mt-24 {
  margin-block-start: var(--space-24);
}

.mr-24 {
  margin-inline-end: var(--space-24);
}

.mb-24 {
  margin-block-end: var(--space-24);
}

.ml-24 {
  margin-inline-start: var(--space-24);
}

.gap-24 {
  gap: var(--space-24);
}

.gap-x-24 {
  column-gap: var(--space-24);
}

.gap-y-24 {
  row-gap: var(--space-24);
}

.m-auto {
  margin: auto;
}

.mx-auto {
  margin-inline: auto;
}

.my-auto {
  margin-block: auto;
}

@media (hover: none) and (pointer: coarse) {
  .shortcut-hint {
    display: none !important;
  }
}
/* ─── SCREEN-READER-ONLY TEXT (`.visually-hidden`) ───────────────────────────
   THE RECIPE IS LOAD-BEARING AND EVERY DECLARATION IN IT IS DOING A JOB.
   This is not a spacing rule that happens to contain a margin. It is a single
   indivisible clip: the box is shrunk to 1px, `overflow` and `clip`/`clip-path`
   crush what is inside it to nothing, and `margin: -1px` pulls that 1px box
   back over its own edge so it cannot contribute a visible pixel of layout.

   `margin: -1px` and `padding: 0` are therefore CLIP GEOMETRY, not rhythm.
   Substituting a spacing token for either one moves the element OUT of its own
   clip rect and paints hidden screen-reader text on the page — a failure that
   shows up as garbage text in front of a customer and that no visual test in
   this estate would catch. A sweep, a linter or a future author must leave
   these two values exactly as they are.

   WHAT ACTUALLY GUARDS THAT, precisely: `tools/ci/check-css-shapes.php` in the
   platform holds all three spellings of this recipe in its `[promoted]` section,
   which is a HARD GATE — a template that re-declares the set fails the build and
   is told to adopt the class. That is protection against the recipe being
   RE-HAND-ROLLED. Nothing anywhere protects the values in THIS file from being
   edited, and no automated sweeper exists that would tokenise them; the
   protection there is this comment and nothing else. Do not read the guard as
   permission to stop being careful here.

   DOCUMENT-SCOPED, AND THAT IS A REAL LIMIT. A class only reaches nodes in the
   document tree. Anything inside a shadow root — a component's internals, and
   also anything the page hands to a component that renders into its own shadow
   root, such as an `astra-table` cell — is untouched by this rule and renders
   FULLY VISIBLE if you give it the class and assume it worked. That single
   constraint is why ~15 Astra components each carry their own copy of the
   recipe rather than using this one, and why `affiliate-payouts.php` reads the
   declarations back out of this rule at runtime and applies them inline. Check
   `el.getRootNode() === document` before trusting the class.

   Both clip spellings ship on purpose. `clip` is the legacy form and is still
   what several engines honour most reliably inside a `position: absolute`
   subtree; `clip-path: inset(50%)` is the modern one and is unaffected by
   `clip` being deprecated. Carrying both is how the recipe stays correct
   whichever one a given engine ignores — and it is what the estate's own
   copies were already split between, six writing `clip` and two `clip-path`.

   NOT focusable-safe by design. A skip link that must APPEAR when tabbed to
   needs the `:not(:focus)` variant, which is a different behaviour and would
   silently un-hide the live regions that make up every current use in the
   estate. If a skip link ever lands, give it its own class rather than
   loosening this one.

   Use it for: `role="status"` live regions announcing a copy-to-clipboard
   receipt, a `<label>` naming a control whose purpose is already visually
   obvious, a heading that structures a page for a screen reader without
   appearing in the design.
   ─────────────────────────────────────────────────────────────────────────── */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ─── ONE AUTHOR PER GAP (`.page-stack`) ────────────────────────────────────
   THE SPACING RULE THIS ESTATE KEPT BREAKING, written down as a class.
   `.page-header` carries `margin-block-end: var(--space-6)` because most pages
   stack it in normal block flow, where a margin is the only way to say "leave
   room under me". But a page whose own root is a flex or grid column ALSO owns
   a `gap` — and then two things are describing the same piece of empty space
   and the answer is their sum, which is never a step of the scale. The payouts
   console is the worked example: `.payouts { gap: var(--space-5) }` (20px) plus
   the header's own 24px put 44px between the heading block and the queue, and
   the owner read it as exactly what it is — "too much padding" (2026-09-04) —
   with no single number anywhere in the source to change.

   A page that wants the stack to own the rhythm says so with this class, and
   the header stops carrying a second opinion. There is deliberately no variant
   for a different gap: a page needing a different rhythm re-points
   `--page-stack-gap` on its own element (see the properties below), and the
   header still contributes nothing.

   UPDATED 2026-09-06: the class used to say "set `gap` on your own element".
   Do not — the section rung is DERIVED from `--page-stack-gap`, so a bare
   `gap` override changes the rhythm without changing the derivation and the
   space above a heading stops being the number that is declared. Re-point the
   property instead; it moves both. */
.page-stack {
  /* THE THREE NUMBERS, PUBLISHED AS PROPERTIES so a page can re-tune its own
     rhythm without writing a margin on anything. Override THESE, never `gap`:
     the section rung is derived from the base one below, and setting `gap`
     directly leaves the derivation reading a value the stack is no longer
     using.

     WHY THESE LADDERS. The base gap is vertical rhythm between siblings
     (`stack`); the section rung is page-level section rhythm (`layout`), which
     is the ladder whose whole job is "how far apart are two sections of a
     page"; the heading rung is again sibling rhythm, one step down, because a
     heading and the thing it titles are siblings that belong together. */
  --page-stack-gap: var(--space-stack-xl); /* 24px — between siblings */
  --page-stack-section-gap: var(--space-layout); /* 32px — above a heading  */
  --page-stack-heading-gap: var(--space-stack); /* 12px — below a heading  */
  display: flex;
  flex-direction: column;
  gap: var(--page-stack-gap);
  min-width: 0;
}

/* ─── THE SAME FAULT ONE LEVEL DOWN: THE STACKED HEADING ────────────────────
   `.page-stack` ended the double gap between a page HEADER and the page. It did
   not end it between a page and its own section headings, and the moment the
   class was rolled out to 86 templates that is where the fault reappeared —
   because a stack's `gap` and a heading's `margin-block-start` are two
   different properties describing one piece of empty space, so the answer is
   their sum and no single number in any file is it.

   MEASURED, /payouts/attention at 390pt: 56px between the page subtitle and the
   first h2 — 8px of the tabs strip's own bottom margin, plus the stack's 24px
   gap, plus the template's own 24px heading margin. Three authors, one gap, and
   the owner's word for the result was that the sections look adrift.

   THE RULE, and it is the whole of it:

     INSIDE A .page-stack, THE STACK DECIDES EVERY VERTICAL GAP. A direct child
     contributes no block margin of its own. A SECTION HEADING (h2-h6) gets
     --page-stack-section-gap above it and --page-stack-heading-gap below it;
     everything else gets --page-stack-gap. To change any of them, change the
     property — do not write a margin.

     Two exemptions, both narrow and both argued below: a bare `h1` (a page
     title, whose rhythm belongs to .page-header) and `.visually-hidden` (whose
     negative margin is clip geometry, not spacing).

   WHY THE CALC, WHICH IS THE PART TO READ BEFORE EDITING. A flex `gap` cannot
   be varied per child, so the heading's own margin is the only way to say "more
   air here". That margin ADDS to the gap — which is the fault — so what is
   written is the DIFFERENCE, and what is DECLARED is the total. Read
   `--page-stack-section-gap: 32px` and the space above a heading is 32px; there
   is one number and it is the true one. The negative below is the same
   arithmetic in the other direction and is safe for the same reason the estate's
   other negative-margin pairings are not: both halves are derived by calc from
   --page-stack-gap in one rule, in one file, so re-tuning the gap moves them
   both and they cannot be edited apart.

   WHY THE CLASS IS DOUBLED. `.attention h2` is (0,1,1) and lives in a page's
   own <style>, which is parsed after core.css — so a normal `.page-stack > h2`
   would tie on specificity and lose on source order, and the rule above would
   be true everywhere except the pages that actually have the fault. (0,2,1)
   wins that comparison, which is what makes the rule a rule rather than a
   default. A page that genuinely wants different spacing has the three
   properties; it does not need to out-specify the system to get it.

   FIRST AND LAST CHILD ARE ZEROED. A heading opening a stack must not push the
   page down by a gap that has nothing above it, and a heading closing one must
   not pull the stack's bottom edge up by the negative.

   `.visually-hidden` IS EXEMPT FROM THE RESET, AND THAT IS THE ONE LINE HERE
   THAT WOULD HAVE BROKEN PRODUCTION SILENTLY. Its `margin: -1px` is not
   rhythm — it is CLIP GEOMETRY, half of an indivisible recipe that pulls a 1px
   box back over its own edge (utilities/_utilities.scss carries the whole
   argument). This reset out-specifies that rule at (0,2,0) against (0,1,0), so
   without the exemption every screen-reader-only span that happens to be a
   direct child of a page stack loses the block half of its clip offset. It is
   already the case on one page in the estate — `portal/shop-order-detail`
   opens its stack with one — and the failure mode is hidden text painting on a
   customer's screen, which no test here would see. `:not(:where(…))` because
   `:where()` contributes ZERO specificity: the exemption must not quietly make
   this rule harder to override than the line above claims it is.

   H1 IS NOT IN THE HEADING SET, DELIBERATELY. A bare `h1` in a stack is a page
   TITLE, and the space under a page title is `.page-header`'s decision (24px,
   the same as the stack's own gap) — not a section break. Treating it as one
   pulled `portal/ads-admin`'s title 12px closer to its content, which is a
   restyle of a page that has no fault, to make a rule tidier. Section headings
   are h2 and below. */
.page-stack.page-stack > *:not(:where(.visually-hidden)) {
  margin-block: 0;
}

.page-stack.page-stack > :is(h2, h3, h4, h5, h6) {
  margin-block-start: calc(var(--page-stack-section-gap) - var(--page-stack-gap));
  margin-block-end: calc(var(--page-stack-heading-gap) - var(--page-stack-gap));
}

.page-stack.page-stack > :is(h2, h3, h4, h5, h6):first-child {
  margin-block-start: 0;
}

.page-stack.page-stack > :is(h2, h3, h4, h5, h6):last-child {
  margin-block-end: 0;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  margin-block-end: var(--space-6);
  /* Do NOT wrap by default. Actions stay anchored to the right at all
     tablet+ widths; the primary section shrinks to make room and the
     title truncates with an ellipsis if necessary. Mobile gets a
     dedicated rule below that restructures the header. */
}

.page-header__primary {
  flex: 1;
  min-width: 0;
}

/* ─── THE SUBTITLE UNDER THE TITLE ──────────────────────────────────────────
   `.page-header__subtitle` was MARKUP WITH NO RULE BEHIND IT. This file has
   documented it in the pattern's own example since the pattern was extracted
   (see the markup sketch above), four payouts templates write it, and nothing
   anywhere in Astra ever styled it — so it inherited `p { margin: 0 }` from
   base/_typography.scss and rendered at body size in `--text-primary`, flush
   against the heading. Measured on the rendered payouts console: a 0px gap at
   390pt AND at 1280px, at 15px, at the h1's own colour. On a phone, where the
   h1 wraps to two lines, that is a subtitle indistinguishable from a third line
   of the title — which is exactly what the owner reported (2026-09-05: "the 'JW
   GROUP LIMITED · one company's books at a time' text also seems too close to
   the text above it").

   THE VALUES ARE NOT INVENTED — THEY ARE THE ESTATE'S, ADOPTED. Sixteen
   templates across two portals independently wrote the same subtitle rule under
   sixteen local names (`.overview__scope`, `.rail__scope`, `.setup__scope`,
   `.content-item__sub`, `.guide__lede`, `.prog__scope`, …), fourteen of them
   byte for byte: `margin: var(--space-1) 0 0; color: var(--text-secondary);
   font-size: var(--text-sm)`. That is a decision the estate has already taken
   and re-taken; it simply had no home. This is the home, and the numbers are
   theirs, so a template adopting the DS class swaps one rule for none and moves
   nothing on screen.

   SPACE COMES FROM THE STACK LADDER, NOT THE RAW SCALE (docs/SPACING-WORKLIST
   §0.3): this is a VERTICAL gap between two siblings, so `--space-stack-xs`.
   It resolves to the same 4px `--space-1` those sixteen copies hardcode, and it
   halves under `[data-density="compact"]` where a hardcoded 4 would not.

   FOUR PIXELS ONLY BECAUSE THE TYPE IS DOING THE REST OF THE WORK. The gap was
   never the whole complaint — a 15px near-white line 0px under a 30px near-white
   line reads as one block whatever the margin is. Dropping to `--text-sm` and
   `--text-secondary` is what makes it a subtitle; the 4px is what stops the two
   line boxes touching. Measured together at 390pt they separate cleanly, and at
   1280px, where the h1 is one line, the header does not loosen — the block grows
   by 4px and the title's own `margin-block-end` is untouched. A larger step was
   tried and is wrong on desktop: `--space-stack-sm` puts 8px between a one-line
   title and its subtitle and the pair stops reading as one unit.

   Scoped to `.page-header__subtitle` and NOT to `.page-header__primary > h1 + p`,
   deliberately. The generic selector would out-specify all sixteen of those
   local class rules (0,1,1 beats 0,1,0) and silently restyle sixteen pages that
   are not broken — a DS rule reaching past its own class to overrule templates
   is how a design system loses trust. Those pages adopt this class when someone
   is looking at them; until then they keep their own copy and nothing moves. */
.page-header__subtitle {
  margin-block-start: var(--space-stack-xs);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.page-header__actions {
  display: flex;
  gap: var(--space-2);
  /* THE ZONE HOLDS STATE, NOT ONLY ACTIONS. Now that a record's current state
     reads as an astra-badge here (and the transitions that change it live in
     the `⋯`), the zone has a child that is NOT 40px tall. The default
     `align-items: stretch` inflated that badge to the height of the tallest
     button beside it — a 40px pill with 12px of text in it — and every page
     that wanted a badge in the header had to reach into the zone and undo the
     stretch itself. Centre the cross axis once, here: buttons are all one
     height so it changes nothing for them, and a wrapped zone centres each
     line rather than the block.
     The ≤768px collapse below is keyed on `astra-button`, so the badge stays
     visible on a phone — which is correct: an operator must be able to see
     what state a record is in without opening a menu. */
  align-items: center;
  /* The zone is ONE flex item and it never shrinks — a shrunken zone is a
     clipped control, and the platform rule is that an ACTIONABLE CONTROL MUST
     NEVER CLIP (the title is what gives way; it has `min-width: 0` above and
     re-flows). `max-width` is the escape hatch for the pathological zone that
     is wider than the header itself: it then wraps INSIDE the zone rather than
     overflowing the page. */
  flex-shrink: 0;
  flex-wrap: wrap;
  max-width: 100%;
}

/* Same guarantee one level down: nothing in the zone shrinks. A squeezed
   astra-button clips its label instead of getting narrower gracefully. The
   cluster is `display: contents`, so ITS children are flex items of the zone
   too and need the rule as well. */
.page-header__actions > *,
.page-header__cluster > * {
  flex-shrink: 0;
}

/* ─── A HEADING THAT CARRIES A COUNT (`.count-title`) ───────────────────────
   Nineteen NineFive templates declared this rule, seventeen of them byte for
   byte, and a nine-line comment explaining WHY had been copy-pasted alongside
   it into ten of them. The idiom was understood and written down; it simply had
   no home, so it propagated by clipboard. This is that home, and this is the
   one copy of the reasoning:

   THE COUNT BELONGS INSIDE THE HEADING, IN ITS INLINE FLOW. "Shop orders 128"
   is one fact, not a title with a statistic parked beside it, and a screen
   reader must read it as one phrase — which is why the badge is a CHILD of the
   h1 and carries its own `aria-label` spelling the noun out ("128 orders"),
   rather than sitting in the actions zone or in a stats card. Putting it in the
   flow also means the pair truncates and wraps as a unit at narrow widths
   instead of the number being orphaned onto its own line.

   `align-items: center` is doing the optical work: a badge is a short pill and
   a heading is a tall line box, so aligning their boxes' tops leaves the pill
   floating near the ascenders. Centring puts it on the heading's optical
   middle. `flex-wrap: wrap` is what stops a long title plus its badge from
   forcing the whole console wider than the viewport on a phone.

   NOT named `.page-header__count`, deliberately. Three of the twenty-two uses
   are an h2 or h3 titling a section INSIDE a card, not the page's own h1, and a
   `__` name would have claimed an ownership that does not hold — it would also
   have meant editing markup in twenty-two files to rename a class that is
   already correct. The rule lives here because the page header is where it
   usually appears; it is scoped to nothing so it keeps working anywhere a
   heading counts something. */
.count-title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

/* An actions GROUP that needs its own element (state-machine host, form
   wrapper). Transparent to layout at BOTH breakpoints: a real flex item would
   introduce a nested row with its own gap, so the group's buttons would space
   differently from a bare child of the zone. */
.page-header__cluster {
  display: contents;
}

/* ─── THE SPLIT PRIMARY: the joined shape ───────────────────────────────────
   Width-independent half of `.page-cta-split` (see the long comment beside
   `$split-pinned` at the top of this file). The POSITIONING halves live in the
   two media blocks below, because a split is pinned exactly where and when its
   primary would have been. */
.page-cta-split {
  display: inline-flex;
  align-items: center;
}

/* THE WRAPPER IS ONLY AS AVAILABLE AS ITS PRIMARY. `hidden` goes on the button
   (the AVAILABILITY CONTRACT), and the corner scrim / bar strip / reserved zone
   all disappear with it — so the caret must go too, or a lone chevron floats in
   the corner over nothing, opening a menu of alternatives to an action that is
   not on offer. Written as the negation of the promotion gate so the two can
   never disagree. */
.page-cta-split:not(:has(> astra-button[variant=primary]:not([hidden]))) {
  display: none;
}

/* ONE CONTROL WITH A SEAM, not two buttons that happen to touch: the inner
   corners collapse and the END half's own (already-present, transparent) 1px
   border becomes the hairline between the halves. Logical radii + a logical
   border edge, so the shape flips correctly in RTL with no second rule.

   BY POSITION, NOT BY ROLE. These used to say "the direct-child primary
   flattens its end corners, the dropdown trigger flattens its start corners",
   which silently required the labelled action to be child #1 and the caret to
   be child #2 — i.e. it hard-coded one arrangement of the halves at the same
   time as the file hard-coded one verb for them. Start/end says the same thing
   about the SHAPE while leaving both free. */
.page-cta-split > astra-button:first-child::part(button), .page-cta-split > astra-dropdown:first-child > astra-button[slot=trigger]::part(button) {
  border-start-end-radius: 0;
  border-end-end-radius: 0;
}

.page-cta-split > astra-button:last-child::part(button), .page-cta-split > astra-dropdown:last-child > astra-button[slot=trigger]::part(button) {
  border-start-start-radius: 0;
  border-end-start-radius: 0;
  border-inline-start-color: color-mix(in oklch, var(--text-on-accent) 30%, transparent);
}

/* The primary's hover lifts it 1px (`transform: translateY(-1px)`), which on a
   joined control tears the seam open and slides the hairline out of true. Both
   halves keep every other hover affordance — the gradient still brightens, the
   elevation still grows — they just do not move. */
.page-cta-split astra-button::part(button):hover {
  transform: none;
}

/* ─── MIRROR ITEMS ──────────────────────────────────────────────────────────
   A `[data-mirror]` menu item is the ≤768px copy of a control that is VISIBLE
   in the zone at this width — so at this width it must not render, or the
   action reads twice (once as a button, once in the ⋯). The ≤768px half of the
   pair is in the mobile block. */
astra-menu-item[data-mirror] {
  display: none;
}

/* …and when they are ALL that a ⋯ holds, the trigger goes too — that decision
   is astra-dropdown's, from what actually renders (see "WITHDRAWAL" there).
   CSS cannot make it: `:has()` can spot a menu whose every item is a mirror,
   but not one emptied by a page's own `hidden`, a permission gate or a state
   machine, and those are the same dead control. */
/* …and the divider that fenced the mirror group off goes with it, or a menu
   whose mirrors are all hidden opens with a stray rule across its top. Keyed on
   the divider FOLLOWING a mirror: in the canonical order (mirrors, then plain
   items, then divider, then the destructive one) a divider only ever sits
   directly after a mirror when the group above it just emptied out.

   `astra-dropdown`'s divider hygiene now catches this case too, and every case
   this selector cannot see — including a menu resized while CLOSED, which the
   component re-judges at every width change rather than at the next open. This
   rule STAYS for what remains: the two react on different clocks. The media
   query flips synchronously the instant the viewport crosses 768px; the JS pass
   is coalesced into the next animation frame. Without this rule that gap is one
   painted frame of stray rule across the top of an open menu. */
astra-menu-item[data-mirror] + astra-menu-divider {
  display: none;
}

/* Card chrome for the `.page-header--sticky` band, at BOTH breakpoints: mobile
   drops the pinning (see the mobile block) but keeps the grouping the card
   creates — title + status chips + facts read as one operator object. The
   pinning itself lives in the ≥769px block at the bottom of this file. */
.page-header--sticky {
  padding: var(--space-4);
  background: var(--surface-raised);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-card);
  box-shadow: var(--elevation-1);
}

@media (max-width: 768px) {
  /* Vertical real estate the sticky CTA bar reserves at the bottom of the
     viewport: 3rem button + space-3 above + space-3 below + safe-area
     inset. Defined ONLY when the page actually renders a promoted CTA, so
     pages without one keep the shells' 12px fallback breathing room. */
  :root:has(.page-header__actions > astra-button[variant=primary]:not([hidden]), .page-header__cluster > astra-button[variant=primary]:not([hidden]), astra-button.page-cta[variant=primary]:not([hidden]), astra-button.page-cta--pinned[variant=primary]:not([hidden])) {
    --page-action-bar-zone: calc(3rem + var(--space-3) + var(--space-3) + env(safe-area-inset-bottom, 0px));
  }
  /* ─── THE ACTION ZONE at ≤768px ───────────────────────────────────────────
     ONE LAYOUT MODEL AT EVERY WIDTH. The header stays the flex row it is on
     desktop; mobile only adds (a) permission to wrap and (b) a floor under the
     title. Title + secondaries + ⋯ therefore share the heading row here exactly
     as they do at 1280px, which is the whole point: an operator does not learn
     a second layout on a phone.

     THIS USED TO BE A GRID, and that is the bug this replaces. `.page-header`
     became `grid-template-areas: "primary dropdown"`, `.page-header__actions`
     dissolved with `display: contents`, and an area was assigned to exactly ONE
     child — `astra-dropdown`. Every other child (a ghost secondary, a
     state-machine button) had no area, so it AUTO-PLACED onto a new implicit
     row: measured on a 375px portal page, two ghosts landed BELOW the header at
     y=232 and squeezed the h1 from 319px to 194px. Three templates shipped
     three different local workarounds for that one bug (invoice-edit,
     shop-order-detail, shop-return-detail) — the cost of a placement rule that
     only knows about one kind of child.

     Placing the whole ZONE (`grid-area` on `.page-header__actions` instead of
     on the dropdown) would have fixed the symptom. Dropping the grid fixes the
     CLASS: with the zone as a single flex item there is nothing left to place,
     so a cluster wrapper, a tooltip host around a button, or tomorrow's second
     dropdown cannot fall out of it. Flex also buys the two behaviours the grid
     could not express here:
       · the zone wraps AS A WHOLE — it may drop under the title, but it can
         never interleave with it or split its own controls across rows;
       · `min-width` on `.page-header__primary` is a REAL floor. `minmax(0, 1fr)`
         asks the title to collapse toward zero before anything else gives; a
         floor makes the ZONE yield the row instead, which is the correct
         priority when the title is what identifies the record.
     (Container queries were the third option: they would need a named container
     on every shell plus a fallback for pages rendered outside one, to arrive at
     these same two declarations. Not worth it.) */
  .page-header {
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-block-end: var(--space-5);
  }
  .page-header__primary {
    /* TITLE FLOOR — under ~12rem a heading stops being readable, so that is the
       width at which the zone gives up the row rather than the title giving up
       characters. `min()` keeps it honest inside a container narrower than the
       floor: never wider than 100%, so the floor itself can never cause an
       overflow. */
    min-width: min(100%, 12rem);
  }
  /* COLLAPSE TO THE ⋯ ALONE.
     The narrow-width answer for a zone that HAS an overflow menu: hide the
     visible secondaries, let the ⋯ carry them, and the heading row is title +
     one 40px trigger.

     Gated on the menu actually containing the mobile copies
     (`astra-menu-item[data-mirror]` — see "MIRROR ITEMS" above), which makes
     the rule fail-safe in the only direction that matters: a zone whose
     secondaries are not mirrored keeps them (they merely wrap under the title,
     as one block), so no page can lose an action by being rebuilt on this file
     before its ⋯ is written.

     The promoted primary is excluded: it is already `position: fixed` in the
     thumb bar, not in this row. `[slot="trigger"]` excludes the ⋯ itself — the
     one control the collapse exists to keep. */
  .page-header__actions:has(astra-dropdown astra-menu-item[data-mirror]) astra-button:not([slot=trigger]):not([variant=primary]):not(.page-cta):not(.page-cta--pinned) {
    display: none;
  }
  /* The other half of the pair (default is `display: none`, above). */
  astra-menu-item[data-mirror] {
    display: block;
  }
  astra-menu-item[data-mirror] + astra-menu-divider {
    display: block;
  }
  /* Sticky primary CTA at the viewport bottom.

     THE INLINE INSET IS THE PAGE GUTTER, the block inset is the shell frame's
     own 12px. Both used to be a flat `var(--space-3)`, and that was right while
     the shell frame was also a flat 12px: the bar sat exactly on the frame's
     edge and read as floating a clean 16px proud of the content inside it.
     Then `--gutter` was wired (tokens/_spacing.scss section 4) and the frame
     collapsed to 0 below 480px, so on a 390px phone the content came to 16px
     from the screen while this bar stayed at 12px — a 4px near-miss, the bar
     overhanging every card on the page by half a hairline, which reads as a
     mistake rather than as a float. `var(--gutter)` puts it back on a line the
     eye can find: one gutter from the screen edge, the same dial the page
     itself reads, so it is flush with the content where the frame is gone and
     floats proud of it where the frame is there. It follows [data-density] for
     free, and the fallback is only for a page that loads this sheet without the
     tokens — `--gutter` is defined on :root at every width.

     `position: fixed`, not absolute: fixed pins to the viewport whatever the
     header is doing, so the bar survived the header being a grid (whose areas
     act as containing blocks for absolutely-positioned children) and survives
     it being a flex row now. It is also why the promoted primary is excluded
     from the collapse above — it is not in that row at all. */
  /* THE PRIMARY LIFTS FOR A DOCKED BAR RATHER THAN DISAPPEARING UNDER ONE.
     `--astra-bottom-dock` is the shared bottom-edge claim (see
     components/_shared/bottom-dock.js): astra-table's selection bar publishes
     its measured height there while it is docked at ≤768px, because it pins to
     this exact corner at this exact z-index and used to land straight on top of
     the CTA — the owner photographed "Start a payout" gone the instant a row
     was ticked (2026-09-04). Unset on every page that has no docked bar, so the
     fallback of 0px is the normal case and this is a no-op there. */
  .page-header__actions > astra-button[variant=primary], .page-header__cluster > astra-button[variant=primary], astra-button.page-cta[variant=primary], astra-button.page-cta--pinned[variant=primary] {
    position: fixed;
    top: auto;
    inset-inline: var(--gutter, var(--space-3));
    /* THE SAFE-AREA INSET IS INSIDE THE DOCK, SO IT MUST NOT BE ADDED TWICE.
       astra-table's docked bar pads its own bottom by
       `calc(var(--space-3) + env(safe-area-inset-bottom, 0px))`, and what it
       publishes as --astra-bottom-dock is getBoundingClientRect().height — the
       whole box, inset included. `max(--space-3, inset) + dock` therefore added
       a SECOND home-indicator height on top of a bar that already cleared it:
       on a 34px-indicator phone the visual gap between this button and the top
       of the bar became 34px instead of 12px. Subtracting the dock inside the
       max is what makes the expression right in both states: with no dock it is
       still `max(12px, inset)`, and with a dock the inset term goes negative and
       the max settles on the 12px gap this button is supposed to have.
       (env() reads 0 in headless Chromium, so this is arithmetic rather than a
       screenshot — noted honestly rather than claimed as measured.) */
    bottom: calc(max(var(--space-3), env(safe-area-inset-bottom, 0px) - var(--astra-bottom-dock, 0px)) + var(--astra-bottom-dock, 0px));
    display: block;
    width: auto;
    z-index: var(--z-overlay);
  }
  /* `display: block` above would defeat the UA's `[hidden] { display:
     none }` (lower specificity) — restore it so hidden CTAs (multi-step
     flows toggling buttons) stay hidden. */
  .page-header__actions > astra-button[variant=primary][hidden],
  .page-header__cluster > astra-button[variant=primary][hidden],
  astra-button.page-cta[variant=primary][hidden],
  astra-button.page-cta--pinned[variant=primary][hidden] {
    display: none;
  }
  .page-header__actions > astra-button[variant=primary]::part(button),
  .page-header__cluster > astra-button[variant=primary]::part(button),
  astra-button.page-cta[variant=primary]::part(button),
  astra-button.page-cta--pinned[variant=primary]::part(button) {
    width: 100%;
    height: 3rem;
    box-shadow: var(--elevation-4);
  }
  /* THE SPLIT PRIMARY IS THE BAR. The wrapper takes the fixed positioning the
     rule above just gave its primary, so the caret rides the bar instead of
     being left behind in the heading row; the primary goes back to being an
     ordinary flex item and eats the width the caret does not need. Gated on the
     wrapper actually holding a PROMOTED primary — an un-promoted split is an
     in-flow control and must stay in the flow. */
  .page-cta-split:has(> astra-button.page-cta[variant=primary]:not([hidden])), .page-cta-split:has(> astra-button.page-cta--pinned[variant=primary]:not([hidden])) {
    position: fixed;
    top: auto;
    inset-inline: var(--gutter, var(--space-3));
    /* The split rides the dock exactly as the single primary above does, and
       sits on the same gutter — the two are the same bar with a different
       number of halves in it, so these insets have to stay identical. */
    /* Same bottom as the single primary above, safe-area arithmetic included —
       see the note there. The split IS that bar with a second half in it, and
       the two expressions have to stay identical or the caret rides at a
       different height from the button it belongs to. */
    bottom: calc(max(var(--space-3), env(safe-area-inset-bottom, 0px) - var(--astra-bottom-dock, 0px)) + var(--astra-bottom-dock, 0px));
    display: flex;
    z-index: var(--z-overlay);
  }
  .page-cta-split > astra-button.page-cta[variant=primary],
  .page-cta-split > astra-button.page-cta--pinned[variant=primary] {
    position: static;
    inset: auto;
    z-index: auto;
    flex: 1 1 auto;
    min-width: 0;
  }
  /* The caret is a fixed 3rem square beside a primary that flexes — the label
     half gives up the width, never the tap target. Same height and elevation as
     the half it is joined to. */
  .page-cta-split > astra-dropdown > astra-button[slot=trigger]::part(button) {
    width: 3rem;
    height: 3rem;
    padding: 0;
    box-shadow: var(--elevation-4);
  }
  /* Backdrop-blur fade strip behind the CTA — iOS Mail / Notes idiom.
     Sits at the viewport bottom, fades from transparent at the top to the
     page surface at the bottom, and blurs whatever scrolls underneath.

     Painted from the SHELL's main slot pseudo (::part(main)::after), i.e.
     a flat-tree ANCESTOR of the promoted button:
       - not the button's own pseudo — the button is a stacking context
         (fixed + z-index), so a pseudo-child would cover its gradient +
         label;
       - not body::after — Chromium paints a fixed body pseudo OVER
         slotted shadow-DOM content regardless of z-index (verified: a
         z-299 body::after covers the z-300 promoted astra-button inside
         astra-shell-admin), so the strip would wash out the CTA.
     A pseudo INSIDE the shell shadow tree layers correctly under the
     button in every shell. body::after remains only as the fallback for
     shell-less pages (plain DOM — z-index behaves normally there).
     mask-image gates the strip's pixels by alpha so the blur dissolves
     toward the top instead of cutting off. */
  astra-shell-admin:has(.page-header__actions > astra-button[variant=primary]:not([hidden]), .page-header__cluster > astra-button[variant=primary]:not([hidden]), astra-button.page-cta[variant=primary]:not([hidden]), astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-partner:has(.page-header__actions > astra-button[variant=primary]:not([hidden]), .page-header__cluster > astra-button[variant=primary]:not([hidden]), astra-button.page-cta[variant=primary]:not([hidden]), astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-ninefive:has(.page-header__actions > astra-button[variant=primary]:not([hidden]), .page-header__cluster > astra-button[variant=primary]:not([hidden]), astra-button.page-cta[variant=primary]:not([hidden]), astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-invoice:has(.page-header__actions > astra-button[variant=primary]:not([hidden]), .page-header__cluster > astra-button[variant=primary]:not([hidden]), astra-button.page-cta[variant=primary]:not([hidden]), astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-identity:has(.page-header__actions > astra-button[variant=primary]:not([hidden]), .page-header__cluster > astra-button[variant=primary]:not([hidden]), astra-button.page-cta[variant=primary]:not([hidden]), astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  body:not(:has(astra-shell-admin, astra-shell-partner, astra-shell-ninefive, astra-shell-invoice, astra-shell-identity)):has(astra-button.page-cta[variant=primary]:not([hidden]))::after {
    content: "";
    position: fixed;
    inset-inline: 0;
    /* THE STRIP RIDES THE DOCK WITH THE BUTTON IT IS BEHIND. Its whole job is
       to keep the CTA off bare content — without it the button is a solid pill
       laid across whatever it happens to be over. When a docked selection bar
       lifts the CTA (see --astra-bottom-dock beside the promoted primary), a
       strip still pinned to bottom:0 is behind the BAR instead, and the button
       is bare again — measured on the payouts queue at 390pt, the lifted CTA
       cut straight across the card the operator had just ticked. */
    bottom: var(--astra-bottom-dock, 0px);
    height: calc(var(--page-action-bar-zone) + var(--space-8));
    background: linear-gradient(to top, var(--surface-page) 0%, color-mix(in oklch, var(--surface-page) 70%, transparent) 60%, transparent 100%);
    backdrop-filter: blur(16px) saturate(180%);
    -webkit-backdrop-filter: blur(16px) saturate(180%);
    mask-image: linear-gradient(to top, rgb(0, 0, 0) 0%, rgb(0, 0, 0) 45%, rgba(0, 0, 0, 0) 100%);
    -webkit-mask-image: linear-gradient(to top, rgb(0, 0, 0) 0%, rgb(0, 0, 0) 45%, rgba(0, 0, 0, 0) 100%);
    z-index: calc(var(--z-overlay) - 1);
    pointer-events: none;
  }
  /* Reserve room under the sticky CTA so the last content row remains
     scrollable into view. Applied at the shell's main slot via
     ::part(main) — gated on a promoted CTA actually existing inside that
     shell so CTA-less pages keep their normal padding. */
  astra-shell-admin:has(.page-header__actions > astra-button[variant=primary], .page-header__cluster > astra-button[variant=primary], astra-button.page-cta[variant=primary], astra-button.page-cta--pinned[variant=primary])::part(main),
  astra-shell-partner:has(.page-header__actions > astra-button[variant=primary], .page-header__cluster > astra-button[variant=primary], astra-button.page-cta[variant=primary], astra-button.page-cta--pinned[variant=primary])::part(main),
  astra-shell-ninefive:has(.page-header__actions > astra-button[variant=primary], .page-header__cluster > astra-button[variant=primary], astra-button.page-cta[variant=primary], astra-button.page-cta--pinned[variant=primary])::part(main),
  astra-shell-invoice:has(.page-header__actions > astra-button[variant=primary], .page-header__cluster > astra-button[variant=primary], astra-button.page-cta[variant=primary], astra-button.page-cta--pinned[variant=primary])::part(main),
  astra-shell-identity:has(.page-header__actions > astra-button[variant=primary], .page-header__cluster > astra-button[variant=primary], astra-button.page-cta[variant=primary], astra-button.page-cta--pinned[variant=primary])::part(main) {
    padding-block-end: calc(var(--page-action-bar-zone, var(--space-3)) + var(--space-3));
  }
  /* Targeted layout wrappers (no-op when nested inside a shell, useful for
     pages rendered outside one) + a body-level reserve for shell-less
     pages that opt a CTA in. */
  .detail-layout,
  .settings-layout,
  .dashboard-grid {
    padding-block-end: calc(var(--page-action-bar-zone, var(--space-3)) + var(--space-3));
  }
  body:not(:has(astra-shell-admin, astra-shell-partner, astra-shell-ninefive, astra-shell-invoice, astra-shell-identity)):has(astra-button.page-cta[variant=primary]:not([hidden])) {
    padding-block-end: calc(var(--page-action-bar-zone, var(--space-3)) + var(--space-3));
  }
  /* Bottom-positioned toast regions ride above the action bar so toasts
     and the CTA never overlap (top-positioned regions are unaffected). */
  :root:has(.page-header__actions > astra-button[variant=primary]:not([hidden]), .page-header__cluster > astra-button[variant=primary]:not([hidden]), astra-button.page-cta[variant=primary]:not([hidden]), astra-button.page-cta--pinned[variant=primary]:not([hidden])) astra-toast-region[position^=bottom] {
    /* …and above a docked selection bar too, which the CTA is now sitting on
       top of (see --astra-bottom-dock beside the promoted primary). */
    bottom: calc(var(--page-action-bar-zone) + var(--astra-bottom-dock, 0px) + var(--space-2));
  }
  /* `.page-header--sticky` does NOT stick on mobile. The thumb-zone bar is the
     mobile answer, and a sticky (= stacking-context-forming) ancestor would trap
     the DS-promoted `position: fixed` CTA inside it, painting it UNDER the action
     bar's blur strip (z-overlay − 1). Static + z-index:auto lets it escape to the
     viewport. The card chrome stays — only the pinning goes. */
  .page-header--sticky {
    position: static;
    z-index: auto;
    padding: var(--space-3);
    border-radius: var(--radius-md);
  }
}
@media (min-width: 769px) {
  /* PIN FLUSH TO THE SCROLLPORT, and no glass anywhere.
     ────────────────────────────────────────────────────────────────────────
     A browser insets a sticky element's constraint rect by the SCROLL
     CONTAINER'S PADDING, so a bare `top: 0` inside the shell's `.sh__main`
     (padding-block-start: space-8) pins the band 32px BELOW the scrollport's
     visible top edge. That leaves a live 32px strip in which scrolled content
     shows ABOVE the supposedly-pinned band.

     This used to be papered over with a `::before` glass panel, and that fix
     was worse than the bug: it painted UNCONDITIONALLY — including at
     scrollTop 0 with nothing beneath it — and it was only as wide as the band
     (the content box) while the scrollport is the content box PLUS the inline
     padding, so it rendered as a 948×32 pale blurred rectangle with hard
     left/right edges that washed the shell's radial accent gradient out at
     rest. Measured on portal shop-order-detail: bbox (289,84)–(1235,173).

     Cancel the inset instead: subtract the container's own top padding, which
     the sidebar shells publish as `--sh-main-pad-block-start`. The band then
     pins flush to the scrollport's visible top edge, so no strip can exist and
     none needs glassing — the card's opaque `--surface-raised` fill and its
     elevation-1 shadow cut the content cleanly on their own.

     At rest nothing moves: sticky only offsets once the element WOULD cross the
     threshold, and at scrollTop 0 the band sits a full padding below it.
     Fallback 0px == today's `top: 0` for any non-shell scroll container with no
     top padding. Mobile keeps `position: static` (see the ≤768px block). */
  .page-header--sticky {
    position: sticky;
    top: calc(-1 * var(--sh-main-pad-block-start, 0px));
    z-index: var(--z-raised);
  }
  /* The floating primary. `position: fixed` (not sticky) because the button
     sits deep inside a card — a sticky box can only travel within its own
     containing block, which is the card, i.e. exactly the scroll range that
     already failed. Bottom-END, so it never collides with the shells' sidebar
     (start) or with the default top-right toast region. */
  astra-button.page-cta--pinned[variant=primary] {
    position: fixed;
    top: auto;
    inset-block-end: var(--space-5);
    inset-inline-end: var(--space-5);
    inset-inline-start: auto;
    z-index: var(--z-overlay);
  }
  /* `[hidden]` must still win (multi-step flows toggle the CTA). */
  astra-button.page-cta--pinned[variant=primary][hidden] {
    display: none;
  }
  astra-button.page-cta--pinned[variant=primary]::part(button) {
    height: 3rem;
    padding-inline: var(--space-6);
    box-shadow: var(--elevation-4);
  }
  /* THE SPLIT PRIMARY, pinned. Same corner, same insets, same z-index as the
     lone pill above — the wrapper simply wears them instead of the button, so
     the caret comes with it. The scrim underneath needs no new selector: it
     gates on `$pinned-visible`, i.e. on the BUTTON, which is still there,
     still classed and still not `hidden`.

     Both declarations below out-specify the `astra-button.page-cta--pinned[variant="primary"]` rules they correct
     (one extra class each) AND sit after them, so neither depends on the other
     mechanism alone. */
  .page-cta-split:has(> astra-button.page-cta--pinned[variant=primary]:not([hidden])) {
    position: fixed;
    top: auto;
    inset-block-end: var(--space-5);
    inset-inline-end: var(--space-5);
    inset-inline-start: auto;
    z-index: var(--z-overlay);
  }
  .page-cta-split > astra-button.page-cta--pinned[variant=primary] {
    position: static;
    inset: auto;
    z-index: auto;
  }
  /* The caret matches the pill it is joined to: 3rem tall, square, same
     elevation. It keeps the pill's `padding-inline` off itself — an icon-only
     button that inherited space-6 either side would be 88px wide. */
  .page-cta-split > astra-dropdown > astra-button[slot=trigger]::part(button) {
    width: 3rem;
    height: 3rem;
    padding: 0;
    box-shadow: var(--elevation-4);
  }
  /* ---- The corner scrim ---------------------------------------------------
     A pill floating over arbitrary scrolling content is only legible if
     something separates it from that content. Mobile solves this with a
     full-width blurred fade strip; a full-width strip is the wrong SHAPE for a
     corner pill — it draws a band across a page that has no band.

     So: the same trick, radially. A quarter-disc of blur anchored in the
     bottom-end corner, and a `mask-image` whose alpha falls to 0 well before
     the box ends, so the blur DISSOLVES outward instead of stopping on an
     edge. Both layers use the same `115% 115%` radial geometry, so the tint
     and the blur fade together — mismatch them and the tint outlives the blur
     as a visible ring.

     Painted from `::part(main)::after`, the same flat-tree ancestor the mobile
     strip uses, for the same two reasons documented there: the button is its
     own stacking context (fixed + z-index) so its own pseudo would cover its
     label, and a fixed `body::after` paints OVER slotted shadow-DOM content in
     Chromium regardless of z-index.

     `pointer-events: none` is non-negotiable — this thing covers ~416x256px of
     real form controls (the product editor's Width/Weight inputs sit under it)
     and would eat every click in that corner.

     No doubling with mobile: that strip lives in the ≤768px block, this in the
     ≥769px block. Exactly one of the two can ever paint. */
  astra-shell-admin:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-partner:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-ninefive:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-invoice:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-identity:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  body:not(:has(astra-shell-admin, astra-shell-partner, astra-shell-ninefive, astra-shell-invoice, astra-shell-identity)):has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::after {
    content: "";
    position: fixed;
    inset-block-start: auto;
    inset-inline-start: auto;
    inset-block-end: 0;
    inset-inline-end: 0;
    inline-size: min(26rem, 38vw);
    block-size: min(16rem, 34vh);
    background: radial-gradient(115% 115% at 100% 100%, color-mix(in oklch, var(--surface-page) 88%, transparent) 0%, color-mix(in oklch, var(--surface-page) 62%, transparent) 42%, transparent 74%);
    backdrop-filter: blur(18px) saturate(180%);
    -webkit-backdrop-filter: blur(18px) saturate(180%);
    mask-image: radial-gradient(115% 115% at 100% 100%, rgb(0, 0, 0) 0%, rgb(0, 0, 0) 34%, rgba(0, 0, 0, 0) 76%);
    -webkit-mask-image: radial-gradient(115% 115% at 100% 100%, rgb(0, 0, 0) 0%, rgb(0, 0, 0) 34%, rgba(0, 0, 0, 0) 76%);
    z-index: calc(var(--z-overlay) - 1);
    pointer-events: none;
  }
  /* `inset-inline-end` is logical but `at 100% 100%` is physical, so in RTL the
     anchor moves to the start edge and the blur would sit on the wrong side of
     its own box. Flip both gradients' origin with it. */
  astra-shell-admin:dir(rtl):has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-partner:dir(rtl):has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-ninefive:dir(rtl):has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-invoice:dir(rtl):has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-identity:dir(rtl):has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  body:dir(rtl):not(:has(astra-shell-admin, astra-shell-partner, astra-shell-ninefive, astra-shell-invoice, astra-shell-identity)):has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::after {
    background: radial-gradient(115% 115% at 0% 100%, color-mix(in oklch, var(--surface-page) 88%, transparent) 0%, color-mix(in oklch, var(--surface-page) 62%, transparent) 42%, transparent 74%);
    mask-image: radial-gradient(115% 115% at 0% 100%, rgb(0, 0, 0) 0%, rgb(0, 0, 0) 34%, rgba(0, 0, 0, 0) 76%);
    -webkit-mask-image: radial-gradient(115% 115% at 0% 100%, rgb(0, 0, 0) 0%, rgb(0, 0, 0) 34%, rgba(0, 0, 0, 0) 76%);
  }
  /* Reserve the pill's zone so the last content row can still scroll clear of
     it, and lift bottom toasts above it — the desktop halves of the two mobile
     rules, gated the same way on the CTA actually existing. */
  :root:has(astra-button.page-cta--pinned[variant=primary]:not([hidden])) {
    --page-action-bar-zone: calc(3rem + var(--space-5) + var(--space-5));
  }
  astra-shell-admin:has(astra-button.page-cta--pinned[variant=primary])::part(main),
  astra-shell-partner:has(astra-button.page-cta--pinned[variant=primary])::part(main),
  astra-shell-ninefive:has(astra-button.page-cta--pinned[variant=primary])::part(main),
  astra-shell-invoice:has(astra-button.page-cta--pinned[variant=primary])::part(main),
  astra-shell-identity:has(astra-button.page-cta--pinned[variant=primary])::part(main) {
    padding-block-end: calc(var(--page-action-bar-zone, var(--space-3)) + var(--space-3));
  }
  :root:has(astra-button.page-cta--pinned[variant=primary]:not([hidden])) astra-toast-region[position^=bottom] {
    bottom: calc(var(--page-action-bar-zone) + var(--space-2));
  }
}
/* Transparency is a preference, not a given. Keep the separation (the pill
   still needs to read against content) but drop the compositor-expensive blur
   and lean on an opaque-at-the-corner tint instead. Same radial falloff, so
   there is still no hard edge. */
@media (min-width: 769px) and (prefers-reduced-transparency: reduce) {
  astra-shell-admin:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-partner:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-ninefive:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-invoice:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  astra-shell-identity:has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::part(main)::after,
  body:not(:has(astra-shell-admin, astra-shell-partner, astra-shell-ninefive, astra-shell-invoice, astra-shell-identity)):has(astra-button.page-cta--pinned[variant=primary]:not([hidden]))::after {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: radial-gradient(115% 115% at 100% 100%, var(--surface-page) 0%, color-mix(in oklch, var(--surface-page) 80%, transparent) 42%, transparent 74%);
  }
}
.brand-mark {
  color: var(--accent-ink);
}

.action-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* Destructive at the start, confirming at the end, whatever the gap between
   them turns out to be. The split is what stops a mis-click, not the label. */
.action-row--split {
  justify-content: space-between;
}

/* Trailing cluster — the default reading for "these are this surface's
   actions" when nothing destructive is present. */
.action-row--end {
  justify-content: flex-end;
}

/* A cluster fenced off from the content above it (the settings "danger zone"
   idiom the five `.danger-row` copies were all reaching for). */
.action-row--fenced {
  padding-block-start: var(--space-4);
  margin-block-start: var(--space-4);
  border-block-start: 1px solid var(--border-subtle);
}

/* Below the thumb-zone breakpoint a wrapped cluster reads as a stack of
   equal-width blocks rather than a ragged row; the DS-promoted primary has
   already left the flow to the bottom bar by then, so what remains here is the
   secondary/destructive tail. */
@media (max-width: 480px) {
  .action-row > astra-button {
    flex: 1 1 auto;
  }
}
/* ─── THE LEADING-ICON NUDGE, AS ONE NAMED VALUE ────────────────────────────
   A status glyph is a square box; the sentence beside it is a line box with
   ascenders, descenders and half-leading. Align their TOPS and the glyph reads
   as sitting slightly high, because the text's own cap height starts a couple
   of pixels down inside its line box. This value is the correction, and it is
   OPTICAL ALIGNMENT TO A BASELINE, not rhythm between two things.

   That distinction is why it is published here as its own property and NOT as
   a spacing token. A spacing token is a statement about how far apart two
   objects should sit, it is re-pointed by density, and it would carry this
   number into every sweep and every ratchet that touches rhythm. This number
   is a property of the type, and it moves only if the icon size or the line
   height moves.

   It is published rather than inlined because the estate proved it has to be:
   sixteen templates re-derived this same correction by hand and landed on five
   different magic numbers (2px, .125rem, .15rem, .1em, .15em) — a spread of
   about 0.4px that nobody can see and that no two authors will ever guess the
   same way twice. A leading icon anywhere in the estate references this, so
   there is one number to re-tune and nothing to grep for.
   ─────────────────────────────────────────────────────────────────────────── */
:root {
  --status-icon-nudge: 2px;
}

.status-surface {
  --status-accent: var(--accent-500);
  --status-ink: var(--accent-ink);
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  flex-wrap: wrap;
  background: radial-gradient(150px 130px at 1.5rem 1.3rem, color-mix(in oklch, var(--status-accent) 26%, transparent) 0%, color-mix(in oklch, var(--status-accent) 9%, transparent) 30%, transparent 68%), var(--status-surface-base, var(--surface-raised));
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  box-shadow: var(--elevation-2);
  padding: var(--space-3) var(--space-4);
  box-sizing: border-box;
}

.status-surface--default {
  --status-accent: var(--accent-500);
  --status-ink: var(--accent-ink);
}

.status-surface--success {
  --status-accent: var(--success-500);
  --status-ink: var(--success-ink);
}

.status-surface--warning {
  --status-accent: var(--warning-500);
  --status-ink: var(--warning-ink);
}

.status-surface--danger {
  --status-accent: var(--danger-500);
  --status-ink: var(--danger-ink);
}

.status-surface--info {
  --status-accent: var(--info-500);
  --status-ink: var(--info-ink);
}

.status-surface--quiet {
  background: color-mix(in srgb, var(--status-accent) 8%, var(--status-surface-base, var(--surface-raised)));
  border-color: color-mix(in srgb, var(--status-accent) 24%, var(--border-subtle));
  box-shadow: none;
}

.status-surface__icon {
  flex-shrink: 0;
  margin-block-start: var(--status-icon-nudge);
  display: inline-flex;
  color: var(--status-ink);
}

.status-surface__content {
  flex: 1 1 14rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.status-surface__title {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  line-height: var(--leading-snug);
}

.status-surface__message {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  line-height: var(--leading-normal);
}

.status-surface__message:empty {
  display: none;
}

.status-surface__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
  flex-wrap: wrap;
  margin-inline-start: auto;
}

/* ─── INLINE — the smallest usable status surface ───────────────────────────
   THE VARIANT THAT EXISTS BECAUSE THE COMPONENT'S ENTRY PRICE WAS TOO HIGH.

   `.status-surface` is adopted in 43 templates, so nobody was unaware of it.
   Seven more places hand-rolled a tinted notice anyway, and the audit found
   why: the canonical form asks for a six-element DOM — `__icon`, `__content`,
   `__title`, `__message`, `__actions` — and what these authors had was ONE
   SENTENCE and an icon. There is no title to write, no secondary message and
   no button, so three quarters of that scaffolding would have been empty
   wrappers. Faced with writing five nested elements or eight lines of CSS,
   they wrote the CSS, and the estate grew a second status idiom with five
   different tints and five different icon nudges.

   The lesson, worth more than the variant: WHEN A COMPONENT IS BEING
   OVERRIDDEN FROM OUTSIDE, CHECK ITS SMALLEST USABLE FORM BEFORE ADDING A
   SPACING PROP. The overrides here were never about the spacing values; they
   were about the DOM.

   WHEN NOT TO REACH FOR THIS, because the survey that found these seven found
   sixteen and the other nine are a DIFFERENT SHAPE. The survey looked for the
   leading-icon nudge, and a nudge is the symptom, not the thing: nine of its
   hits (`.usage__row` ×4, `.checklist li`, `.terms li`, `.bill__notice`,
   `.reports__howpaid-bank`, `.px__preview-promise`) are icon-and-text ROWS, and
   converting them would have put a tinted, bordered, elevated notice around a
   checklist item.

   The line is NOT "does it already have padding and a radius" — four of those
   nine have both, plus a border and a surface fill. It is what the block SAYS:

     · A NOTICE is TONAL and it is ONE SENTENCE. It carries a state — success,
       warning, danger, info — the tone is load-bearing, and the whole block is
       a single statement about the thing beside it. That is this variant.
     · A ROW is NEUTRAL and it is a RECORD. It has columns, often a trailing
       action, and its icon is a type marker rather than a state. Tinting it
       would claim an alarm the author never raised.

   If you cannot name the TONE without inventing one, it is a row.

   So this variant changes the CONTRACT, not the look. Write:

     <p class="status-surface status-surface--inline status-surface--warning" role="status">
       <astra-icon name="alert-circle"></astra-icon>
       <span>We have paid out more than this quarter earned.</span>
     </p>

   A direct `astra-icon` child is treated as the leading glyph — it gets the
   ink colour, it does not shrink and it gets the nudge — so no `__icon`
   wrapper is needed. Everything else beside it is the sentence. `__icon` and
   the full scaffolding still work if a notice later grows a title and actions;
   this is a subset, not a fork.

   WHAT IS DELIBERATELY NOT CHANGED: the padding. The tint is a radial gradient
   whose origin is calibrated to a glyph sitting at `padding-inline:
   var(--space-4)`, and the comment on that gradient says not to re-tune the
   padding without re-tuning the origin. A "compact" inline notice that moved
   the padding would slide the glow off its own icon. An inline notice is
   already shorter than a titled one because it holds one line instead of
   three; it does not also need to be tighter.

   WHAT IS DELIBERATELY DIFFERENT FROM THE HAND-ROLLS IT REPLACES: they set
   `color: var(--warning-ink)` on the whole block, tinting the body text to
   match the glyph. The canonical language does not: `--status-ink` is scoped
   to the ICON, where it only has to clear WCAG's 3:1 floor for non-text UI,
   and the sentence stays `--text-primary`, which is the only value in the
   system proven to clear 4.5:1 against a tinted surface in BOTH themes. Body
   text in an ink colour was the riskier of the two guesses.
   ─────────────────────────────────────────────────────────────────────────── */
.status-surface--inline {
  margin: 0;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  color: var(--text-primary);
  flex-wrap: nowrap;
  gap: var(--space-inline-sm);
}

.status-surface--inline > astra-icon {
  flex: none;
  margin-block-start: var(--status-icon-nudge);
  color: var(--status-ink);
}

.status-surface--inline > :not(astra-icon):not(.status-surface__icon) {
  min-width: 0;
  overflow-wrap: anywhere;
  margin: 0;
}

.status-surface--inline:has(> astra-button) {
  flex-wrap: wrap;
  align-items: center;
  row-gap: var(--space-2);
}
.status-surface--inline:has(> astra-button) > :not(astra-icon):not(.status-surface__icon):not(astra-button) {
  flex: 1 1 10rem;
}
.status-surface--inline:has(> astra-button) > astra-button {
  flex: none;
}

.form-msg {
  margin: 0;
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

.form-msg:empty {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  pointer-events: none;
}

.form-msg--error {
  color: var(--danger-ink);
}

.form-msg--success {
  color: var(--success-ink);
}

.form-msg--muted {
  color: var(--text-secondary);
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-block-end: var(--space-1);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  text-decoration: none;
  border-radius: var(--radius-sm);
  transition: color var(--motion-hover);
}
.back-link astra-icon {
  width: 1rem;
  height: 1rem;
  transition: transform var(--motion-hover);
}
.back-link:hover {
  color: var(--text-primary);
}
.back-link:hover astra-icon {
  transform: translateX(-2px);
}
.back-link:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
@media (pointer: coarse) {
  .back-link {
    min-height: 2.75rem;
  }
}

.editor-opening {
  margin: 0;
  padding: var(--space-6) max(16px, env(safe-area-inset-left, 0px));
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.editor-opening a {
  color: var(--accent-ink);
  font-weight: var(--weight-medium);
}

@media (scripting: none) {
  .editor-opening {
    display: none;
  }
}
.view-tabs {
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  scrollbar-width: none;
  box-shadow: inset 0 -1px 0 var(--border-subtle);
  margin-block-start: calc(-1 * var(--space-2));
}
.view-tabs::-webkit-scrollbar {
  display: none;
}
.view-tabs > a {
  position: relative;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  padding: 0 var(--space-3);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  color: var(--text-secondary);
  text-decoration: none;
  transition: color var(--motion-hover);
}
.view-tabs > a::after {
  content: "";
  position: absolute;
  left: var(--space-2);
  right: var(--space-2);
  bottom: 0;
  height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--accent-500);
  transform: scaleX(0);
  transition: transform var(--motion-moderate) var(--ease-out);
}
.view-tabs > a:hover {
  color: var(--text-primary);
}
.view-tabs > a[aria-current=page], .view-tabs > a[aria-current=true] {
  color: var(--accent-ink);
}
.view-tabs > a[aria-current=page]::after, .view-tabs > a[aria-current=true]::after {
  transform: scaleX(1);
}
.view-tabs > a:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: -2px;
  border-radius: var(--radius-sm);
}
.view-tabs > [aria-current] {
  scroll-initial-target: nearest;
}
@supports (animation-timeline: scroll()) {
  .view-tabs {
    mask-image: linear-gradient(to right, transparent, black var(--view-tabs-fade-start), black calc(100% - var(--view-tabs-fade-end)), transparent);
    animation: view-tabs-fade linear both;
    animation-timeline: scroll(self inline);
  }
}

@property --view-tabs-fade-start {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}
@property --view-tabs-fade-end {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}
@keyframes view-tabs-fade {
  0% {
    --view-tabs-fade-start: 0px;
    --view-tabs-fade-end: 2rem;
  }
  10% {
    --view-tabs-fade-start: 2rem;
  }
  90% {
    --view-tabs-fade-end: 2rem;
  }
  100% {
    --view-tabs-fade-start: 2rem;
    --view-tabs-fade-end: 0px;
  }
}
.view-tabs__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  min-width: 1.5rem;
  height: 1.125rem;
  padding: 0 0.35em;
  border-radius: var(--radius-full);
  background: var(--surface-sunken);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}
[aria-current] > .view-tabs__count {
  background: color-mix(in oklch, var(--accent-500) 14%, transparent);
  color: var(--accent-ink);
}

.filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.filter-chips > a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  box-sizing: border-box;
  min-height: 2rem;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-secondary);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--motion-hover), border-color var(--motion-hover), color var(--motion-hover);
}
.filter-chips > a:hover {
  border-color: var(--border-default);
  color: var(--text-primary);
}
.filter-chips > a[aria-current=page], .filter-chips > a[aria-current=true] {
  background: color-mix(in srgb, var(--accent-500) 10%, var(--surface-raised));
  border-color: color-mix(in oklab, var(--accent-500) 40%, transparent);
  color: var(--accent-ink);
}
.filter-chips > a:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
@media (pointer: coarse) {
  .filter-chips > a {
    min-height: 2.75rem;
  }
}

.filter-chips__count {
  font-variant-numeric: tabular-nums;
}

.panel-grid {
  display: grid;
  gap: var(--space-stack-lg) var(--space-inline-lg);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 1024px) {
  .panel-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.panel-grid > .panel--wide {
  grid-column: 1/-1;
}

.panel-grid--stretch {
  align-items: stretch;
}
.panel-grid--stretch > astra-card::part(card) {
  height: 100%;
  box-sizing: border-box;
}

.panel__title {
  margin: 0;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--text-primary);
}

.panel__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  width: 100%;
}

.panel__link {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--accent-ink);
  text-decoration: none;
}
.panel__link:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.panel__lead {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.item-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
}
.item-list > li + li {
  border-block-start: 1px solid var(--border-subtle);
}

.item-list__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  min-height: 3rem;
  padding: var(--space-2) 0;
  color: inherit;
  text-decoration: none;
}
.item-list__row:is(button) {
  box-sizing: border-box;
  inline-size: calc(100% + 2 * var(--space-2));
  border: 0;
  background: none;
  font: inherit;
  text-align: start;
  cursor: pointer;
}
.item-list__row:is(a, button) {
  margin-inline: calc(-1 * var(--space-2));
  padding-inline: var(--space-2);
  border-radius: var(--radius-sm);
  transition: background-color var(--motion-hover);
}
.item-list__row:is(a, button):hover {
  background: var(--surface-sunken);
}
.item-list__row:is(a, button):focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: -2px;
}
.item-list__row:is(a, button)::after {
  content: "";
  flex-shrink: 0;
  width: 0.4375rem;
  height: 0.4375rem;
  margin-inline: var(--space-1) var(--space-1-5);
  border-block-start: 1.5px solid var(--text-tertiary);
  border-inline-end: 1.5px solid var(--text-tertiary);
  transform: rotate(45deg);
  transition: transform var(--motion-hover);
}
.item-list__row:is(a, button):hover::after {
  transform: translateX(2px) rotate(45deg);
}

.item-list__icon {
  display: inline-grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  color: var(--text-secondary);
}
.item-list__icon astra-icon {
  width: 1rem;
  height: 1rem;
}
.item-list__icon[data-tone=accent] {
  background: color-mix(in oklch, var(--accent-500) 12%, transparent);
  color: var(--accent-ink);
}
.item-list__icon[data-tone=success] {
  background: color-mix(in oklch, var(--success-500) 14%, transparent);
  color: var(--success-ink);
}
.item-list__icon[data-tone=warning] {
  background: color-mix(in oklch, var(--warning-500) 16%, transparent);
  color: var(--warning-ink);
}

.item-list__main {
  display: grid;
  gap: 2px;
  min-width: 0;
  flex: 1 1 8rem;
}

.item-list__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

.item-list__meta {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}

.item-list__end {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-inline-start: auto;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  white-space: nowrap;
}

.item-list:has(> li > :is(a, button).item-list__row) > li > div.item-list__row::after {
  content: "";
  flex: none;
  width: calc(0.4375rem + 1.5px);
  margin-inline: var(--space-1) var(--space-1-5);
}

.item-list--stack {
  container-type: inline-size;
}

@container (max-width: 30rem) {
  .item-list--stack .item-list__row {
    row-gap: var(--space-1);
  }
  .item-list--stack .item-list__row > .item-list__icon {
    align-self: flex-start;
  }
  .item-list--stack .item-list__end {
    order: 3;
    flex-basis: 100%;
    box-sizing: border-box;
    justify-content: flex-start;
    margin-inline-start: 0;
  }
  .item-list--stack .item-list__row:has(> .item-list__icon) > .item-list__end {
    padding-inline-start: calc(2rem + var(--space-3));
  }
}
.kv-list {
  margin: 0;
  display: grid;
}
.kv-list > div {
  display: grid;
  grid-template-columns: minmax(7rem, 38%) minmax(0, 1fr);
  gap: var(--space-3);
  padding: var(--space-2-5, 0.625rem) 0;
  align-items: baseline;
}
.kv-list > div + div {
  border-block-start: 1px solid var(--border-subtle);
}
.kv-list dt {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.kv-list dd {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
@media (max-width: 479.98px) {
  .kv-list > div {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }
}

.checklist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
}
.checklist > li {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.checklist > li > astra-icon {
  width: 1.25rem;
  height: 1.25rem;
  color: var(--text-tertiary);
}
.checklist > li[data-on] > astra-icon {
  color: var(--success-ink);
}
.checklist > li[data-tone=warning] > astra-icon {
  color: var(--warning-ink);
}
.checklist > li[data-tone=danger] > astra-icon {
  color: var(--danger-ink);
}
.checklist > li[data-tone=info] > astra-icon {
  color: var(--info-ink);
}
.checklist strong {
  display: block;
  color: var(--text-primary);
  font-weight: var(--weight-medium);
}

.settings-section {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack-xl) var(--space-layout);
  padding-block: var(--space-stack-xl);
}
.settings-section + .settings-section {
  border-block-start: 1px solid var(--border-subtle);
}
@media (min-width: 1024px) {
  .settings-section {
    grid-template-columns: minmax(12rem, 18rem) minmax(0, 40rem);
    row-gap: var(--space-stack);
  }
}

.settings-section__intro h2, .settings-section__intro h3 {
  margin: 0 0 var(--space-1);
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
}
.settings-section__intro p {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.settings-section__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack);
  min-width: 0;
}

@keyframes astra-enter-fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes astra-enter-rise {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@media (prefers-reduced-motion: no-preference) {
  .enter > * {
    animation: astra-enter-rise var(--motion-moderate) var(--ease-out) backwards;
  }
  .enter > :is(.page-header, :has(.page-cta--pinned)) {
    animation-name: astra-enter-fade;
  }
  .enter > :nth-child(2) {
    animation-delay: 30ms;
  }
  .enter > :nth-child(3) {
    animation-delay: 60ms;
  }
  .enter > :nth-child(4) {
    animation-delay: 90ms;
  }
  .enter > :nth-child(5) {
    animation-delay: 120ms;
  }
  .enter > :nth-child(6) {
    animation-delay: 150ms;
  }
  .enter > :nth-child(n+7) {
    animation-delay: 180ms;
  }
}
body:has(astra-modal[open]) :is(.page-cta, .page-cta--pinned) {
  visibility: hidden;
}

.portal-wordmark {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: var(--weight-bold);
  letter-spacing: 0.04em;
  white-space: nowrap;
}

@media (max-width: 767.98px) {
  .portal-wordmark__site {
    display: none;
  }
}
.copyval, .copyblock {
  --copyval-pad: .25rem;
  border-radius: var(--radius-sm);
  background-color: transparent;
  box-shadow: 0 0 0 var(--copyval-pad) transparent, 0 0 0 calc(var(--copyval-pad) + 1px) transparent;
  transition: background-color 220ms var(--ease-out, ease), box-shadow 220ms var(--ease-out, ease);
}

.copyval {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-1);
  max-width: 100%;
  --copyval-btn: 1.5rem;
  --copyval-btn-inline: var(--copyval-btn);
}

.copyval__text {
  min-width: 0;
  overflow-wrap: anywhere;
}

.copyval__btn::part(button) {
  width: var(--copyval-btn-inline);
  height: var(--copyval-btn);
}

.copyval__btn:not([hidden]) {
  display: flex;
  flex: none;
  block-size: var(--copyval-btn);
  inline-size: var(--copyval-btn-inline);
}

.copyval__btn {
  align-self: flex-start;
  margin-block: 0;
  margin-block: calc((1lh - var(--copyval-btn)) / 2);
}

.copyval__btn, .addr-all {
  opacity: 0.8;
  transition: opacity var(--duration-fast, 120ms) ease;
}

.copyval:hover .copyval__btn, .copyval__btn:focus-visible,
.copyblock:hover .addr-all, .addr-all:focus-visible {
  opacity: 1;
}

.copyval[data-copied], .copyblock[data-copied] {
  background-color: color-mix(in oklab, var(--success-500) 16%, transparent);
  box-shadow: 0 0 0 var(--copyval-pad) color-mix(in oklab, var(--success-500) 16%, transparent), 0 0 0 calc(var(--copyval-pad) + 1px) color-mix(in oklab, var(--success-ink) 40%, transparent);
  transition-duration: 90ms;
}

.copyval[data-copied] .copyval__btn, .copyblock[data-copied] .addr-all {
  opacity: 1;
}

.copyblock {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

@media (prefers-reduced-motion: reduce) {
  .copyval, .copyblock, .copyval__btn, .addr-all {
    transition: none;
  }
}
@media (pointer: coarse) {
  .copyval {
    --copyval-btn-inline: 2rem;
  }
}
.website-row-link {
  display: grid;
  gap: 1px;
  flex: 1;
  min-width: 0;
  padding-block: var(--space-1-5);
  border-radius: var(--radius-sm);
  color: inherit;
  text-decoration: none;
}
.website-row-link:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
.website-row-link:hover .website-row-link__title {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.website-row-link__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.website-row-link__meta {
  font-size: var(--text-xs);
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.website-editor .panel__title {
  min-width: 0;
  overflow-wrap: anywhere;
}

.website-order.action-row {
  display: none;
  justify-content: flex-end;
  margin-block-start: var(--space-3);
}

astra-sortable-list[data-changed] ~ .website-order.action-row {
  display: flex;
}

.website-order__note {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5);
  margin-inline-end: auto;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--warning-ink);
}
.website-order__note astra-icon {
  width: 0.875rem;
  height: 0.875rem;
  flex-shrink: 0;
}

.website-pair {
  display: grid;
  gap: var(--space-stack) var(--space-inline-lg);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 640px) {
  .website-pair {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.website-days {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.website-days > legend {
  padding: 0;
  margin-block-end: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}

.website-title-badge {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  min-width: 0;
}

.website-meta {
  flex-shrink: 0;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.website-subhead {
  margin: var(--space-4) 0 var(--space-1);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.website-fieldset {
  display: grid;
  gap: var(--space-stack);
  margin: 0;
  padding: var(--space-4) 0 0;
  border: 0;
  min-width: 0;
  border-block-start: 1px solid var(--border-subtle);
}
.website-fieldset > legend {
  float: left;
  inline-size: 100%;
  padding: 0;
  margin: 0;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.website-split {
  display: grid;
  gap: var(--space-stack-lg) var(--space-inline-lg);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
.website-split > .website-split__col {
  display: contents;
}
@media (min-width: 1024px) {
  .website-split {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-rows: auto 1fr;
  }
  .website-split.website-split--one {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: none;
  }
  .website-split > .website-split__col {
    display: grid;
    gap: var(--space-stack-lg);
    align-content: start;
    min-width: 0;
  }
  .website-split > .website-split__side {
    grid-column: 2;
    grid-row: 1/span 2;
  }
  .website-split > .website-split__late {
    grid-column: 1;
  }
}

@media (min-width: 1024px) {
  .settings-section.website-section--wide {
    grid-template-columns: minmax(0, 1fr);
  }
}

.website-form-save {
  padding-block: var(--space-stack-xl) 0;
  border-block-start: 1px solid var(--border-subtle);
}
@media (min-width: 1024px) {
  .website-form-save {
    display: grid;
    column-gap: var(--space-layout);
    grid-template-columns: minmax(12rem, 18rem) minmax(0, 40rem);
  }
  .website-form-save > * {
    grid-column: 2;
  }
}

@property --website-fade-start {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}
@property --website-fade-end {
  syntax: "<length>";
  inherits: false;
  initial-value: 0px;
}
@keyframes website-strip-fade {
  0% {
    --website-fade-start: 0px;
    --website-fade-end: 2rem;
  }
  10% {
    --website-fade-start: 2rem;
  }
  90% {
    --website-fade-end: 2rem;
  }
  100% {
    --website-fade-start: 2rem;
    --website-fade-end: 0px;
  }
}
@media (max-width: 767.98px) {
  .website-chips > [aria-current] {
    scroll-initial-target: nearest;
    scroll-snap-align: center;
  }
  @supports (animation-timeline: scroll()) {
    .website-chips {
      mask-image: linear-gradient(to right, transparent, black var(--website-fade-start), black calc(100% - var(--website-fade-end)), transparent);
      animation: website-strip-fade linear both;
      animation-timeline: scroll(self inline);
    }
  }
  .website-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 3px 2px;
  }
  .website-chips::-webkit-scrollbar {
    display: none;
  }
}

.website-checklist > li[data-on] {
  color: var(--text-secondary);
}
.website-checklist > li:not([data-on]) {
  color: var(--text-primary);
}

.website-arrow {
  color: var(--text-tertiary);
  margin-inline: var(--space-1);
}

.website-search {
  display: grid;
  gap: var(--space-2) var(--space-3);
  align-items: start;
  grid-template-columns: minmax(0, 1fr);
  max-inline-size: 40rem;
}
@media (min-width: 640px) {
  .website-search {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .website-search > astra-button {
    margin-block-start: 1.6rem;
  }
}

.website-wording {
  max-inline-size: 48rem;
}

.website-wording__row {
  display: grid;
  gap: var(--space-3);
  padding-block: var(--space-4);
}

.website-wording__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-3);
  min-width: 0;
}
.website-wording__head code {
  font-size: var(--text-xs);
  padding: 2px var(--space-1-5);
  border-radius: var(--radius-sm);
  background: var(--surface-sunken);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}

.website-wording__form {
  display: grid;
  gap: var(--space-stack);
}

.website-roles {
  overflow-x: auto;
}
.website-roles table {
  inline-size: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.website-roles th, .website-roles td {
  padding: var(--space-2) var(--space-2);
  vertical-align: middle;
}
.website-roles thead th {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
  text-align: center;
  white-space: nowrap;
  border-block-end: 1px solid var(--border-default);
}
.website-roles thead th:first-child {
  text-align: start;
  padding-inline-start: 0;
}
.website-roles tbody tr + tr > * {
  border-block-start: 1px solid var(--border-subtle);
}
.website-roles tbody th {
  text-align: start;
  font-weight: var(--weight-regular, 400);
  color: var(--text-primary);
  padding-inline-start: 0;
}
.website-roles td {
  inline-size: 4.5rem;
  text-align: center;
}
.website-roles td astra-checkbox {
  display: inline-flex;
  justify-content: center;
}
.website-roles tr[data-missing] .website-roles__action {
  color: var(--text-secondary);
}
@media (max-width: 479.98px) {
  .website-roles td {
    inline-size: 3.25rem;
    padding-inline: var(--space-1);
  }
}

.website-roles__action {
  display: block;
}

.website-roles__note {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-block-start: 2px;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.website-roles__note astra-icon {
  width: 0.75rem;
  height: 0.75rem;
  flex-shrink: 0;
}

.website-roles__save {
  margin-block-start: var(--space-4);
}

.website-request {
  display: grid;
  gap: var(--space-stack-lg) var(--space-inline-lg);
  align-items: start;
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 1024px) {
  .website-request {
    grid-template-columns: minmax(0, 2fr) minmax(16rem, 1fr);
  }
  .website-request.website-request--one {
    grid-template-columns: minmax(0, 48rem);
  }
}

.website-request__thread {
  display: grid;
  gap: var(--space-stack-lg);
  min-width: 0;
}

.website-thread {
  display: grid;
  gap: var(--space-stack);
}

.website-thread__who {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.website-thread__who astra-icon {
  width: 1rem;
  height: 1rem;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.website-thread__body {
  font-size: var(--text-sm);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.website-thread__body > p {
  margin: 0;
}
.website-thread__body > p + p {
  margin-block-start: var(--space-3);
}

.website-topic {
  display: grid;
  gap: var(--space-stack-lg) var(--space-inline-lg);
  align-items: start;
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 1024px) {
  .website-topic {
    grid-template-columns: minmax(0, 2fr) minmax(18rem, 1fr);
  }
}

.website-topic__side {
  display: grid;
  gap: var(--space-stack-lg);
  min-width: 0;
}

.website-points {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: website-point;
  display: grid;
  gap: var(--space-3);
}
.website-points > li {
  counter-increment: website-point;
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  font-size: var(--text-sm);
  color: var(--text-primary);
  line-height: var(--leading-normal);
}
.website-points > li::before {
  content: counter(website-point);
  display: inline-grid;
  place-items: center;
  inline-size: 1.5rem;
  block-size: 1.5rem;
  border-radius: var(--radius-full);
  background: color-mix(in oklch, var(--accent-500) 12%, transparent);
  color: var(--accent-ink);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

.website-footnote {
  margin-block-start: var(--space-4);
}

.website-gap {
  margin-block-start: var(--space-4);
}

.website-theme__title {
  margin-block-end: var(--space-3);
}

.studio-stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack);
  min-width: 0;
}
.studio-stack > form {
  margin: 0;
}

.studio-count {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.studio-token {
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  border: 1px solid var(--border-subtle);
}
.studio-token code {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.6;
  color: var(--text-primary);
  overflow-wrap: anywhere;
  word-break: break-all;
  user-select: all;
}

.studio-lines {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 2px;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}

@media (min-width: 1024px) {
  .studio-gates {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-layout);
  }
  .studio-gates > li + li {
    border-block-start: 0;
  }
  .studio-gates > li:nth-child(n+3) {
    border-block-start: 1px solid var(--border-subtle);
  }
}

.studio-diff {
  display: grid;
  gap: var(--space-2);
  min-width: 0;
}

.studio-diff__title {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}
.studio-diff__title code {
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

.studio-diff__code {
  margin: 0;
  padding-block: 0;
  overflow: auto;
  max-height: 28rem;
  border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
  font-size: var(--text-xs);
  line-height: 1.6;
}
.studio-diff__code > code {
  display: block;
  min-width: max-content;
}
.studio-diff__code:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}

.studio-diff__line {
  display: block;
  padding-inline: var(--space-3);
  white-space: pre;
}
.studio-diff__line:first-child {
  padding-block-start: var(--space-2);
}
.studio-diff__line:last-child {
  padding-block-end: var(--space-2);
}
.studio-diff__line[data-sign=added] {
  background: color-mix(in oklab, var(--success-500) 14%, transparent);
  color: var(--text-primary);
}
.studio-diff__line[data-sign=removed] {
  background: color-mix(in oklab, var(--danger-500) 12%, transparent);
  color: var(--text-primary);
}
.studio-diff__line[data-sign=kept] {
  color: var(--text-secondary);
}

.studio-actions {
  display: grid;
  min-width: 0;
}
.studio-actions > .settings-section:first-child {
  padding-block-start: 0;
}
.studio-actions > .settings-section:last-child {
  padding-block-end: 0;
}

.studio-actions form {
  scroll-margin-block-start: var(--space-layout);
}

.studio-resign {
  margin-block-start: var(--space-stack);
}

.studio-resign__form {
  display: grid;
  gap: var(--space-stack);
  max-width: 40rem;
  margin: 0;
  padding-block-end: var(--space-stack);
}

.engagement-section {
  display: grid;
  gap: var(--space-stack);
  min-width: 0;
}
.engagement-section > h2, .engagement-section > .engagement-section__head > h2 {
  margin: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--text-primary);
}
.engagement-section .count-title {
  gap: var(--space-2);
}

.engagement-section__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  min-height: 2.25rem;
}

.engagement-note {
  margin: 0;
  max-width: 68ch;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.engagement-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack-lg);
  margin: 0;
}

.engagement-pair {
  display: grid;
  gap: var(--space-stack) var(--space-inline-lg);
  align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr));
}

.engagement-pair--wide {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

.engagement-short {
  max-width: 14rem;
}

.engagement-winner__action {
  margin-block-start: var(--space-stack);
}
@media (max-width: 480px) {
  .engagement-winner__action astra-button {
    display: block;
  }
  .engagement-winner__action astra-button::part(button) {
    width: 100%;
  }
}

.engagement-winner__history {
  margin: var(--space-stack-sm) 0 0;
  padding-inline-start: var(--space-5);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.engagement-winner__history li {
  overflow-wrap: anywhere;
}

.engagement-redraw {
  display: grid;
  gap: var(--space-stack);
}

.engagement-publish-link {
  padding-block-start: var(--space-stack-sm);
  border-block-start: 1px solid var(--border-subtle);
}

.engagement-master {
  display: grid;
  gap: var(--space-stack-xl);
  min-width: 0;
  align-items: start;
  grid-template-columns: minmax(0, 1fr);
}
.engagement-master > astra-card {
  min-width: 0;
}
.engagement-master > astra-card > .panel__title {
  flex: 1 1 calc(100% - 3rem);
  min-width: 0;
  overflow-wrap: anywhere;
}
.engagement-master > astra-card > .engagement-master__close {
  order: 1;
}
.engagement-master > astra-card > .page-header__actions {
  order: 2;
}
@media (min-width: 1280px) {
  .engagement-master:has(> astra-card:not([hidden])) {
    grid-template-columns: minmax(0, 1fr) minmax(18rem, 24rem);
  }
}

.engagement-actions {
  margin-block-start: var(--space-stack-lg);
}

.team-subhead {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--text-primary);
}

summary.team-subhead {
  cursor: pointer;
  border-radius: var(--radius-sm);
}

summary.team-subhead:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}

.team-setup [aria-busy=true] {
  opacity: 0.62;
  transition: opacity var(--motion-hover);
}

.team-bill > li > .item-list__row {
  min-height: 0;
  padding-block: var(--space-2);
}
.team-bill .item-list__end {
  font-variant-numeric: tabular-nums;
  color: var(--text-primary);
}

.team-row-actions {
  margin-block-start: calc(-1 * var(--space-1));
  padding-block-end: var(--space-3);
  padding-inline-start: calc(2rem + var(--space-3));
}

.company-stats {
  display: grid;
  gap: var(--space-inline-lg);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
}
@media (max-width: 768px) {
  .company-stats {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2);
  }
}

.company-attention__title {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}
.company-attention__title astra-icon {
  width: 1rem;
  height: 1rem;
  flex: none;
  color: var(--text-secondary);
}

@media (min-width: 1024px) {
  .company-attach {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-layout);
  }
  .company-attach > li + li {
    border-block-start: 0;
  }
  .company-attach > li:nth-child(n+3) {
    border-block-start: 1px solid var(--border-subtle);
  }
}

.company-attach__meter {
  inline-size: 4rem;
  flex: none;
}

.company-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack);
}

.company-pairs {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack);
}
@media (min-width: 640px) {
  .company-pairs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-stack) var(--space-inline-lg);
  }
}

.company-fgroup {
  display: grid;
  gap: var(--space-stack);
}

.company-fgroup__title {
  margin: var(--space-2) 0 0;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.company-form > .company-fgroup__title:first-child {
  margin-block-start: 0;
}

.company-fgroup__note {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.company-done {
  display: grid;
  gap: var(--space-stack-lg);
}

.company-ack-list {
  list-style: none;
  margin: var(--space-2) 0 0;
  padding: 0;
  display: grid;
  gap: var(--space-1);
  font-size: var(--text-sm);
}
.company-ack-list a {
  color: var(--accent-ink);
  font-weight: var(--weight-medium);
}

.company-console {
  height: 100%;
  min-height: 0;
}

.company-ticket .ticket__panel, .company-chat .chat-panel {
  flex: 1;
  min-height: 20rem;
  display: grid;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--surface-raised);
  box-shadow: var(--elevation-1);
}

.company-chat .chat-panel {
  grid-template-columns: minmax(16rem, 21rem) minmax(0, 1fr);
}
.company-chat .chat-panel[data-empty="1"] {
  grid-template-columns: minmax(0, 1fr);
}
.company-chat .chat-panel[data-empty="1"] .pane-conv {
  display: none;
}
.company-chat .chat-panel[data-empty="1"] .pane-list {
  border-inline-end: 0;
}
.company-chat .chat-panel[data-empty="1"] {
  flex: none;
  min-height: 0;
}
.company-chat .pane-list {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  border-inline-end: 1px solid var(--border-subtle);
}
.company-chat .pane-list__scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-2);
}
.company-chat .pane-conv {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}
.company-chat .thread-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.company-chat .thread {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  text-align: start;
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  transition: background-color var(--motion-hover);
}
.company-chat .thread:hover {
  background: var(--surface-sunken);
}
.company-chat .thread:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: -2px;
}
.company-chat .thread.is-active {
  background: color-mix(in oklch, var(--accent-500) 10%, transparent);
}
.company-chat .thread.is-active:hover {
  background: color-mix(in oklch, var(--accent-500) 14%, transparent);
}
.company-chat .thread astra-avatar {
  flex: none;
}
.company-chat .thread__main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.company-chat .thread__top, .company-chat .thread__bottom {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}
.company-chat .thread__bottom {
  align-items: center;
}
.company-chat .thread__name {
  flex: 1;
  min-width: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.company-chat .thread.is-unread .thread__name {
  font-weight: var(--weight-semibold);
}
.company-chat .thread__time {
  flex: none;
  font-size: var(--text-2xs);
  color: var(--text-tertiary);
  white-space: nowrap;
}
.company-chat .thread__preview {
  flex: 1;
  min-width: 0;
  font-size: var(--text-xs);
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.company-chat .thread.is-unread .thread__preview {
  color: var(--text-primary);
}
.company-chat .thread__dot {
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--accent-500);
}
.company-chat .thread--skeleton {
  cursor: default;
}
.company-chat .thread--skeleton:hover {
  background: none;
}
.company-chat .conv__head {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 3.25rem;
  padding: var(--space-2) var(--space-3);
  border-block-end: 1px solid var(--border-subtle);
  background: var(--surface-raised);
}
.company-chat .conv__back {
  display: none;
  flex: none;
}
.company-chat .chat-panel[data-pane=list] .conv__head {
  display: none;
}
.company-chat .conv__id {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.company-chat .conv__id h2 {
  margin: 0;
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.company-chat .conv__sub {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.company-chat .conv__tools {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
}
.company-chat #conv-chat {
  flex: 1;
  min-height: 0;
}
@media (max-width: 820px) {
  .company-chat .chat-panel {
    grid-template-columns: minmax(0, 1fr);
  }
  .company-chat .chat-panel[data-pane=list] .pane-conv {
    display: none;
  }
  .company-chat .chat-panel[data-pane=conv] .pane-list {
    display: none;
  }
  .company-chat .pane-list {
    border-inline-end: 0;
  }
  .company-chat .conv__back {
    display: inline-flex;
  }
  .company-chat .conv__head {
    flex-wrap: wrap;
    row-gap: var(--space-1);
  }
  .company-chat .conv__id {
    min-width: 8rem;
  }
}

@media (max-width: 820px) {
  .company-chat:has(.chat-panel[data-pane=conv]) > :is(.page-header, astra-tabs) {
    display: none;
  }
}
.company-chat__hint {
  flex: 1;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-6);
  font-size: var(--text-sm);
  color: var(--text-tertiary);
  text-align: center;
}
.company-chat__hint astra-icon {
  width: 1rem;
  height: 1rem;
  flex: none;
}

.company-ticket .ticket__panel {
  min-height: 18rem;
  grid-template-columns: 16rem minmax(0, 1fr);
}
.company-ticket .ticket__aside {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-4);
  background: var(--surface-sunken);
  border-inline-end: 1px solid var(--border-subtle);
  overflow-y: auto;
  min-height: 0;
}
.company-ticket .aside-id {
  min-width: 0;
  max-width: 100%;
}
.company-ticket .aside-name {
  font-weight: var(--weight-semibold);
  font-size: var(--text-md);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.company-ticket .aside-sub {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
  overflow-wrap: anywhere;
}
.company-ticket .aside-mail {
  color: var(--accent-ink);
  text-decoration: none;
}
.company-ticket .aside-mail:hover {
  text-decoration: underline;
}
.company-ticket .ticket__facts {
  width: 100%;
  margin: var(--space-4) 0 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.company-ticket .ticket__facts > div {
  display: flex;
  justify-content: space-between;
  gap: var(--space-2);
  font-size: var(--text-xs);
}
.company-ticket .ticket__facts dt {
  color: var(--text-tertiary);
  margin: 0;
}
.company-ticket .ticket__facts dd {
  color: var(--text-primary);
  margin: 0;
  font-weight: var(--weight-medium);
  overflow-wrap: anywhere;
  text-align: end;
}
.company-ticket .ticket__convo {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
}
.company-ticket .ticket__convo > .status-surface {
  flex: none;
  border-radius: 0;
  border-inline: 0;
  border-block-start: 0;
  box-shadow: none;
}
.company-ticket #ticket-chat {
  flex: 1;
  min-height: 0;
}
.company-ticket .convo__closed {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-block-start: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
@media (max-width: 820px) {
  .company-ticket .ticket__panel {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }
  .company-ticket .ticket__aside {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    text-align: start;
    border-inline-end: 0;
    border-block-end: 1px solid var(--border-subtle);
    padding: var(--space-3) var(--space-4);
    overflow: visible;
  }
  .company-ticket .aside-id {
    flex: 1;
  }
  .company-ticket .ticket__facts {
    margin: 0;
    flex-basis: 100%;
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
  }
  .company-ticket .ticket__facts > div {
    gap: var(--space-1);
  }
}

.company-disclosure {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  background: var(--surface-raised);
}
.company-disclosure > summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 2.75rem;
  padding: 0 var(--space-4);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-primary);
  cursor: pointer;
  list-style: none;
  border-radius: inherit;
}
.company-disclosure > summary::-webkit-details-marker {
  display: none;
}
.company-disclosure > summary astra-icon {
  width: 1rem;
  height: 1rem;
  color: var(--text-secondary);
}
.company-disclosure > summary::after {
  content: "";
  margin-inline-start: auto;
  width: 0.4375rem;
  height: 0.4375rem;
  border-block-end: 1.5px solid var(--text-tertiary);
  border-inline-end: 1.5px solid var(--text-tertiary);
  transform: rotate(45deg);
  transition: transform var(--motion-hover);
}
.company-disclosure > summary:hover {
  background: var(--surface-sunken);
}
.company-disclosure > summary:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: -2px;
}
.company-disclosure[open] > summary::after {
  transform: rotate(-135deg);
}
.company-disclosure > form {
  padding: 0 var(--space-4) var(--space-4);
}

.company-client .company-client__hint:empty {
  display: none;
}

.company-client__grid {
  display: grid;
  gap: var(--space-stack-lg) var(--space-inline-lg);
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}
@media (min-width: 1100px) {
  .company-client__grid {
    grid-template-columns: minmax(0, 1fr) minmax(19rem, 22rem);
  }
}
@media (max-width: 1099.98px) {
  .company-client__grid > .company-client__main, .company-client__grid > .company-client__side {
    display: contents;
  }
  .company-client__grid .company-client__account {
    order: -1;
  }
}

.company-client__main, .company-client__side {
  display: grid;
  gap: var(--space-stack-lg);
  grid-template-columns: minmax(0, 1fr);
  min-width: 0;
}

.company-client__headline {
  margin: 0 0 var(--space-3);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.company-client__total {
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.company-client__list {
  flex-basis: 100%;
  font-variant-numeric: tabular-nums;
}

.company-client__link-out {
  margin: var(--space-3) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.company-client .bill {
  display: grid;
  margin-block-end: var(--space-3);
}
.company-client .bill__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-1-5) 0;
  font-size: var(--text-sm);
  color: var(--text-primary);
}
.company-client .bill__label {
  min-width: 0;
  overflow-wrap: anywhere;
}
.company-client .bill__detail {
  display: block;
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}
.company-client .bill__amount {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.company-client .bill__row--credit .bill__amount {
  color: var(--success-ink);
}
.company-client .bill__row--total {
  margin-block-start: var(--space-2);
  padding-block-start: var(--space-3);
  border-block-start: 1px solid var(--border-subtle);
  font-weight: var(--weight-semibold);
}
.company-client .rowset {
  display: grid;
}
.company-client .rowline {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--space-3);
  align-items: center;
  box-sizing: border-box;
  min-height: 3rem;
  padding-block: var(--space-1-5);
  font-size: var(--text-sm);
}
.company-client .rowline--module {
  grid-template-columns: minmax(0, 1fr) 3.5rem minmax(5.5rem, auto);
}
.company-client .rowline--module > astra-badge {
  justify-self: center;
}
.company-client .rowline--module > .price-edit {
  justify-self: end;
}
.company-client .rowset > * + .rowline {
  border-block-start: 1px solid var(--border-subtle);
}
.company-client .rowset > .status-surface {
  margin-block-end: var(--space-2);
}
.company-client .rowline__name {
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: var(--weight-medium);
  color: var(--text-primary);
}
.company-client .rowline__sub {
  display: block;
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  color: var(--text-secondary);
}
.company-client .rowline__money {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.company-client .rowline--module .rowline__name {
  overflow-wrap: normal;
}
.company-client .rowline--module :is(.rowline__label, .rowline__sub) {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 560px) {
  .company-client .rowline:not(.rowline--module) {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .company-client .rowline:not(.rowline--module) .rowline__money {
    grid-column: 1/-1;
  }
}
@media (max-width: 400px) {
  .company-client .rowline--module {
    grid-template-columns: minmax(0, 1fr) 2.75rem 4.75rem;
    gap: var(--space-2);
  }
  .company-client .rowline--module :is(.rowline__label, .rowline__sub) {
    white-space: normal;
    overflow: visible;
    overflow-wrap: anywhere;
  }
}
.company-client .price-edit {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  margin-block: calc(-1 * var(--space-1));
  margin-inline-end: calc(-1 * var(--space-2));
  border-radius: var(--radius-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  transition: background-color var(--motion-hover), color var(--motion-hover);
}
.company-client .price-edit:hover {
  background: color-mix(in oklch, var(--accent-500) 10%, transparent);
  color: var(--accent-ink-on-tint);
}
.company-client .price-edit:active {
  background: color-mix(in oklch, var(--accent-500) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--accent-500) 22%, transparent);
}
.company-client .price-edit:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
@media (pointer: coarse) {
  .company-client .price-edit::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: max(100%, 44px);
    transform: translateY(-50%);
  }
}
.company-client .price-edit__pencil {
  opacity: 0;
  color: var(--text-tertiary);
  transition: opacity var(--motion-hover);
}
.company-client .price-edit:is(:hover, :focus-visible) .price-edit__pencil {
  opacity: 1;
  color: currentColor;
}
@media (hover: none) {
  .company-client .price-edit__pencil {
    opacity: 0.55;
  }
}
.company-client .preview[aria-busy=true] {
  opacity: 0.55;
}
.company-client .preview__figures {
  font-variant-numeric: tabular-nums;
}

.shop-collections .tree__row {
  padding-inline: calc(var(--space-2) + var(--shop-tree-level, 0) * 1.5rem) var(--space-2);
}

.shop-collections .tree__row:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: -2px;
}

@media (pointer: coarse) {
  .shop-collections .tree__row {
    min-height: 44px;
    padding-block: var(--space-3);
  }
}
.shop-collections .tree__count {
  font-variant-numeric: tabular-nums;
}
.shop-collections .tree-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
.shop-collections .assign__head {
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
}
.shop-collections .assign {
  display: grid;
  gap: var(--space-2);
  max-height: 20rem;
  overflow: auto;
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
@media (max-width: 640px) {
  .shop-collections .assign {
    max-height: none;
    overflow: visible;
  }
}

.shop-meta .shop-meta__values {
  margin-inline-start: var(--space-6);
}
.shop-meta .shop-meta__values .item-list__row {
  min-height: 2.5rem;
}
.shop-meta .shop-meta__none {
  margin: 0 0 var(--space-2) var(--space-6);
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
@media (max-width: 479.98px) {
  .shop-meta .shop-meta__values, .shop-meta .shop-meta__none {
    margin-inline-start: var(--space-4);
  }
}

.shop-rules form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
.shop-rules .rule-effect {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-primary);
}
.shop-rules .probe {
  display: grid;
  gap: var(--space-4);
}
.shop-rules .probe__fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
.shop-rules #probe-out:empty {
  display: none;
}

.shop-coupons form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
.shop-coupons .scope {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.shop-coupons .scope__effect {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-primary);
}
.shop-coupons .scope__note {
  margin: 0 0 var(--space-3);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.shop-coupons .scope__group {
  display: grid;
  gap: var(--space-2);
}
.shop-coupons .chipset {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}
.shop-coupons .chipset:empty {
  display: none;
}
.shop-coupons .chipset__chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  max-width: 100%;
  padding: var(--space-0-5, 0.125rem) var(--space-1) var(--space-0-5, 0.125rem) var(--space-2-5, 0.625rem);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-full);
  background: var(--surface-raised);
  font-size: var(--text-sm);
}
.shop-coupons .chipset__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 14rem;
}
.shop-coupons .chipset__chip button {
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  line-height: 1;
  padding: var(--space-0-5, 0.125rem) var(--space-1);
  border-radius: var(--radius-full);
  color: var(--text-secondary);
}
.shop-coupons .chipset__chip button:hover {
  background: color-mix(in oklch, var(--text-primary) 8%, transparent);
  color: var(--text-primary);
}
.shop-coupons .chipset__chip button:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 1px;
}
.shop-coupons .scope .cpal__chip > button:first-child {
  display: none;
}
.shop-coupons .scope .cpal__list {
  max-height: 11rem;
}

.shop-products .qe-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  overflow-wrap: anywhere;
}
.shop-products .qe-head__line {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  min-width: 0;
}
.shop-products .qe-head__title {
  margin: 0;
  min-width: 0;
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  line-height: var(--leading-snug);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}
.shop-products .qe-head__desc {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
  line-height: var(--leading-normal);
}
.shop-products .qe-head__desc:empty {
  display: none;
}
.shop-products #edit-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
.shop-products .qe-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}
@media (max-width: 479.98px) {
  .shop-products .qe-fields {
    grid-template-columns: minmax(0, 1fr);
  }
}
.shop-products .qe-facts {
  display: grid;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-subtle);
}
.shop-products .qe-facts__title {
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}
.shop-products astra-table::part(shop-name) {
  display: grid;
  gap: 2px;
  min-width: 0;
}
.shop-products astra-table::part(shop-name--variant) {
  padding-inline-start: var(--space-4);
}
.shop-products astra-table::part(shop-name-title) {
  overflow-wrap: anywhere;
}
.shop-products astra-table::part(shop-name-meta) {
  font-size: var(--text-xs);
  font-weight: var(--weight-regular);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.shop-products astra-table::part(shop-name-warn) {
  font-size: var(--text-xs);
  color: var(--warning-ink);
  overflow-wrap: anywhere;
}
.shop-products astra-table::part(shop-before) {
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.shop-products astra-table::part(shop-after) {
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.shop-products .bulk {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
}
.shop-products .bulk__form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
.shop-products .bulk__params {
  display: grid;
  gap: var(--space-3);
  align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
}
@media (max-width: 479.98px) {
  .shop-products .bulk__params {
    grid-template-columns: minmax(0, 1fr);
  }
}
.shop-products .bulk__panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle);
  background: var(--surface-sunken);
}
.shop-products .bulk__confirm {
  margin: 0;
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}
.shop-products .bulk__note {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}
.shop-products .bulk__note:empty {
  display: none;
}
.shop-products .bulk__strips {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2);
}
.shop-products .bulk__strips:empty {
  display: none;
}
.shop-products .bulk__counts {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}
.shop-products .bulk__totals {
  margin: 0;
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
}
.shop-products .bulk__skips {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.shop-products .bulk__section-title {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.shop-pf__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack-lg) var(--space-inline-lg);
  align-items: start;
}
@media (min-width: 1280px) {
  .shop-pf__grid {
    grid-template-columns: minmax(0, 1fr) minmax(17.5rem, 21.25rem);
  }
}

.shop-pf #page-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
  min-width: 0;
}

.shop-pf__col {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack-lg);
  min-width: 0;
}

.shop-pf__stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
  min-width: 0;
}

.shop-pf__fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
  gap: var(--space-3);
}

.shop-pf__fields--pairs {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 479.98px) {
  .shop-pf__fields--pairs {
    grid-template-columns: minmax(0, 1fr);
  }
}

.shop-pf__bullets {
  display: grid;
  gap: var(--space-2);
}

.shop-pf__bullets:empty {
  display: none;
}

.shop-pf__bullet {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-2);
  align-items: end;
}

.shop-pf__picture-note {
  color: var(--warning-ink);
}

.shop-pf #f-information {
  min-height: 14rem;
}

.shop-order .order-detail__addr .addr-line {
  display: block;
}
.shop-order .addr-line + .copyblock {
  margin-block-start: var(--space-2);
}
.shop-order .order-head__title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.shop-order .order-head__title h1 {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}
.shop-order .order-head__facts {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-4);
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.shop-order .order-head__facts strong {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}
.shop-order .order-head__facts .fact {
  display: inline-flex;
  gap: var(--space-1-5);
  align-items: baseline;
}
@media (max-width: 479.98px) {
  .shop-order .order-head__facts {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .shop-order .order-head__facts .fact:first-child {
    grid-column: 1/-1;
  }
}
.shop-order form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
.shop-order .shop-order__section {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
  min-width: 0;
}
.shop-order .shop-order__stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack-lg) var(--space-inline-lg);
  min-width: 0;
}
.shop-order .kv-list address {
  font-style: normal;
  line-height: var(--leading-relaxed, 1.6);
}
.shop-order .kv-list .note {
  white-space: pre-line;
}
.shop-order .notes-thread {
  display: grid;
  gap: var(--space-2);
  margin-block-end: var(--space-3);
  max-height: 18rem;
  overflow: auto;
}
@media (max-width: 640px) {
  .shop-order .notes-thread {
    max-height: none;
    overflow: visible;
  }
}
.shop-order .note-item {
  display: grid;
  gap: var(--space-1);
  justify-items: start;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.shop-order .note-item__meta {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}
.shop-order .note-item__body {
  margin: 0;
  justify-self: stretch;
  font-size: var(--text-sm);
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.shop-order .note-item--internal {
  border-color: color-mix(in srgb, var(--warning-500) 40%, var(--border-default));
  background: color-mix(in srgb, var(--warning-500) 8%, var(--surface-raised));
}
.shop-order .trk-lines {
  display: grid;
  gap: var(--space-3);
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.shop-order .trk-lines legend {
  padding: 0;
  margin-block-end: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.shop-order .trk-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-2) var(--space-3);
  align-items: start;
}
.shop-order .trk-line__flags {
  grid-column: 1/-1;
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin: 0;
}
.shop-order .trk-line astra-button {
  align-self: center;
}
.shop-order .trk-read {
  display: grid;
  gap: var(--space-1);
  margin: 0 0 var(--space-1);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.shop-order .trk-read__id {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-weight: var(--weight-semibold);
}
.shop-order .trk-read__meta, .shop-order .trk-read__note {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.shop-order .trk-read__note:empty {
  display: none;
}
.shop-order astra-table::part(trk-cell) {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  max-width: 100%;
}
.shop-order astra-table[data-view=cards]::part(trk-cell) {
  display: flex;
  justify-content: flex-end;
}
.shop-order astra-table::part(trk-chip) {
  max-width: 100%;
  min-width: 0;
}
@media (hover: hover) and (pointer: fine) {
  .shop-order .order-detail__addr .copyval__btn {
    opacity: 0;
  }
  .shop-order .order-detail__addr .copyval:is(:hover, :focus-within, [data-copied]) .copyval__btn {
    opacity: 1;
  }
}
.shop-order .addr-all {
  margin-inline-start: calc(-1 * var(--space-3) - 1px);
}
@media (max-width: 768px) {
  .shop-order .order-head astra-menu-item[data-mirror][hidden] {
    display: none;
  }
}

.shop-rd .rd__cards {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack-lg);
}
.shop-rd .rd__titlekey {
  white-space: nowrap;
}
.shop-rd .rd__linehead {
  display: flex;
  gap: var(--space-1) var(--space-3);
  align-items: baseline;
  flex-wrap: wrap;
}
.shop-rd .rd__meta {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.shop-rd .rd__reason {
  margin: var(--space-2) 0 var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.shop-rd .rd__cardactions {
  flex-wrap: nowrap;
}
@media (max-width: 560px) {
  .shop-rd .rd__cardactions {
    flex: 1 1 100%;
    flex-wrap: wrap;
  }
  .shop-rd .rd__cardactions > astra-button {
    flex: 0 0 auto;
  }
}
.shop-rd .rd__cards astra-card[data-dirty] {
  border-radius: var(--radius-card);
  outline: 2px solid color-mix(in oklch, var(--warning-500) 65%, transparent);
  outline-offset: 2px;
}
.shop-rd .rd__progress {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  flex-wrap: wrap;
}
.shop-rd .rd__progress astra-stepper {
  flex: 1 1 22rem;
  min-width: 0;
}
.shop-rd .rd__rejected {
  flex: 1 1 auto;
  align-items: center;
  flex-wrap: wrap;
  row-gap: var(--space-2);
}
.shop-rd .rd__rejected > span {
  flex: 1 1 10rem;
}
.shop-rd .rd__rejected > astra-button {
  flex: none;
}
@media (max-width: 640px) {
  .shop-rd .rd__progress {
    align-items: flex-start;
    flex-direction: column;
  }
  .shop-rd .rd__progress astra-stepper {
    flex: none;
    align-self: stretch;
  }
}
.shop-rd .rd__notes {
  margin-top: var(--space-4);
}
.shop-rd .rd__trackers {
  display: grid;
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.shop-rd .rd__tracker {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}
.shop-rd .rd__trkbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.shop-rd .rd__trkgrid {
  display: grid;
  gap: var(--space-3);
  align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}
.shop-rd .trk-grp {
  display: grid;
  gap: var(--space-2);
  align-content: start;
  min-width: 0;
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.shop-rd .trk-grp__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}
.shop-rd .trk-grp__lede {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.shop-rd .trk-state {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin: 0;
  font-size: var(--text-sm);
}
.shop-rd .trk-state__file {
  font-weight: var(--weight-semibold);
  overflow-wrap: anywhere;
}
.shop-rd .trk-state__ok {
  color: var(--success-ink);
  flex-shrink: 0;
}
.shop-rd .trk-state__text {
  flex: 1 1 12rem;
  min-width: 0;
  overflow-wrap: anywhere;
}
.shop-rd .trk-label-link {
  margin-inline-start: calc(-1 * var(--space-3) - 1px);
}
.shop-rd .trk-state__why {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.shop-rd .trk-state__why:empty {
  display: none;
}
.shop-rd .trk-fields {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-3);
}
.shop-rd .trk-grp astra-file-upload::part(list) {
  display: none;
}
.shop-rd .rd__addrow {
  margin-top: var(--space-4);
}

.shop-console__form {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (max-width: 479.98px) {
  .shop-console__form {
    grid-template-columns: minmax(0, 1fr);
  }
}

.shop-console__wide {
  grid-column: 1/-1;
}

.shop-console__checks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
}

.finance-pairs {
  display: grid;
  gap: var(--space-stack) var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

.finance-more > summary {
  cursor: pointer;
  width: fit-content;
  min-height: 2.75rem;
  display: flex;
  align-items: center;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--accent-ink);
  border-radius: var(--radius-sm);
}
.finance-more > summary:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
.finance-more[open] > summary {
  margin-block-end: var(--space-3);
}

.finance-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.finance-toolbar > .filter-chips {
  flex: 1 1 auto;
  min-width: 0;
}

.finance-toolbar__end {
  margin-inline-start: auto;
}

.finance-stats {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 768px) {
  .finance-stats {
    grid-template-columns: repeat(var(--finance-stats-cols, 4), minmax(0, 1fr));
  }
}
@media (max-width: 767.98px) {
  .finance-stats > :last-child:nth-child(odd) {
    grid-column: 1/-1;
  }
}

.finance-figure {
  margin: 0 0 var(--space-2);
  font-size: var(--text-2xl);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  color: var(--text-primary);
}

.finance-lead-gap {
  margin-block-start: var(--space-3);
}

.finance-gap {
  margin-block-start: var(--space-4);
}

.finance-quiet {
  display: block;
  margin-block-start: 2px;
  font-size: var(--text-xs);
  color: var(--text-secondary);
}

.finance-radios {
  display: grid;
  gap: var(--space-3);
}

.finance-email-preview {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}
.finance-email-preview h3 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-secondary);
}
.finance-email-preview p {
  margin: 0 0 var(--space-2);
}
.finance-email-preview p:last-child {
  margin-block-end: 0;
}

.finance-payouts .queue__filters {
  display: flex;
  gap: var(--space-3);
  align-items: flex-end;
  flex-wrap: wrap;
}
.finance-payouts .queue__filters astra-tabs {
  flex: 1 1 22rem;
  min-width: 0;
}
.finance-payouts .queue__filters astra-select {
  flex: 0 1 16rem;
  min-width: 0;
}
.finance-payouts .queue__filters:not(:has(> :not([hidden]))) {
  display: none;
}
.finance-payouts .queue__ref {
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: var(--text-sm);
  user-select: all;
}
.finance-payouts .queue__send {
  display: grid;
  gap: var(--space-3);
  margin-block-start: var(--space-4);
}
.finance-payouts .queue__notice {
  margin-block-start: var(--space-3);
}
.finance-payouts .queue__pager {
  margin-block-start: var(--space-2);
}

.finance-invoices__tools {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}
.finance-invoices__tools astra-tabs {
  flex: 1 1 20rem;
  min-width: 0;
}
.finance-invoices__tools:not(:has(> :not([hidden]))) {
  display: none;
}

.finance-invoice .page-header__subtitle {
  overflow-wrap: anywhere;
}

.finance-invoice__chase {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.finance-invoice__chase astra-icon {
  flex: none;
  color: var(--text-tertiary);
}
.finance-invoice__chase[hidden] {
  display: none;
}

.finance-invoice__fields {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
}

.finance-invoice__linkout {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: end;
}
.finance-invoice__linkout astra-input {
  flex: 1 1 18rem;
  min-width: 0;
}

.finance-invoice__lines {
  display: grid;
}

.finance-invoice__line {
  display: grid;
  gap: var(--space-2) var(--space-3);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding-block: var(--space-4);
}
.finance-invoice__line + .finance-invoice__line {
  border-block-start: 1px solid var(--border-subtle);
}
.finance-invoice__line:first-child {
  padding-block-start: 0;
}
.finance-invoice__line > .l-item_name {
  grid-column: 1/-1;
}
.finance-invoice__line > astra-button {
  grid-column: 1/-1;
  justify-self: end;
  order: 9;
}
@media (max-width: 479.98px) {
  .finance-invoice__line {
    grid-template-columns: minmax(0, 1fr);
  }
}

.finance-invoice__fields--pair {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
}

.finance-invoice__line-desc {
  grid-column: 1/-1;
}

.finance-invoice__add {
  margin-block-start: var(--space-1);
}

.finance-invoice__sums {
  display: grid;
  gap: var(--space-1);
  justify-items: end;
  margin: var(--space-4) 0 0;
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--border-subtle);
}
.finance-invoice__sums > div {
  display: flex;
  gap: var(--space-4);
  align-items: baseline;
}
.finance-invoice__sums dt {
  margin: 0;
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.finance-invoice__sums dd {
  margin: 0;
  min-width: 6rem;
  text-align: end;
  font-variant-numeric: tabular-nums;
}
.finance-invoice__sums .is-total dt {
  color: var(--text-primary);
  font-weight: var(--weight-medium);
}
.finance-invoice__sums .is-total dd {
  font-weight: var(--weight-semibold);
  font-size: var(--text-lg);
}

.finance-quotes .finance-quotes__row {
  align-items: flex-start;
  padding-block: var(--space-3);
}
.finance-quotes .finance-quotes__row > .item-list__end {
  padding-block-start: 2px;
}
.finance-quotes .finance-quotes__warn {
  color: var(--warning-ink);
}
@media (max-width: 479.98px) {
  .finance-quotes .finance-quotes__row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
    column-gap: var(--space-3);
    row-gap: var(--space-1);
  }
  .finance-quotes .finance-quotes__row > .item-list__icon {
    grid-row: 1/span 2;
  }
  .finance-quotes .finance-quotes__row > .item-list__end {
    grid-column: 2;
    grid-row: 1;
    justify-self: start;
    padding: 0;
  }
  .finance-quotes .finance-quotes__row > .item-list__main {
    grid-column: 2;
  }
}
.finance-quotes .finance-quotes__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-block-start: var(--space-2);
}
.finance-quotes .finance-quotes__actions > form {
  margin: 0;
}
.finance-quotes .finance-quotes__actions > astra-button {
  flex: none;
}
.finance-quotes .finance-quotes__days {
  display: grid;
  gap: var(--space-stack) var(--space-3);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.finance-quotes #quote-form:has(astra-radio-group[name="deposit[kind]"][value=none]) .finance-quotes__deposit-value {
  display: none;
}
.finance-quotes .finance-quotes__line {
  display: grid;
  gap: var(--space-2) var(--space-3);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  padding-block: var(--space-4);
  border-block-start: 1px solid var(--border-subtle);
}
.finance-quotes .finance-quotes__line > .finance-quotes__line-title, .finance-quotes .finance-quotes__line > .finance-quotes__what, .finance-quotes .finance-quotes__line > astra-checkbox {
  grid-column: 1/-1;
}
@media (max-width: 479.98px) {
  .finance-quotes .finance-quotes__line {
    grid-template-columns: minmax(0, 1fr);
  }
}
.finance-quotes .finance-quotes__line:first-child {
  border-block-start: 0;
  padding-block-start: 0;
}
.finance-quotes .finance-quotes__line-title {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}
.finance-quotes .finance-quotes__more {
  border-block-start: 1px solid var(--border-subtle);
  padding-block-start: var(--space-3);
}
.finance-quotes .finance-quotes__more > summary {
  cursor: pointer;
  width: fit-content;
  min-height: 2.75rem;
  display: flex;
  align-items: center;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--accent-ink);
  border-radius: var(--radius-sm);
}
.finance-quotes .finance-quotes__more > summary:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
.finance-quotes .finance-quotes__more > .finance-quotes__line:first-of-type {
  border-block-start: 0;
}

.finance-pub {
  max-width: 60rem;
  margin: 0 auto;
  padding: var(--space-5) var(--space-4) var(--space-8);
}
.finance-pub > * + * {
  margin-block-start: var(--space-5);
}
.finance-pub .pub__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
}
.finance-pub .pub__title {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}
.finance-pub .pub__title h1 {
  margin: 0;
  overflow-wrap: anywhere;
}
.finance-pub .pub__facts {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2) var(--space-5);
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.finance-pub .pub__facts strong {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}
.finance-pub .pub__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
}
@media (min-width: 768px) {
  .finance-pub .pub__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 768px) {
  .finance-pub .pub__grid > astra-card:only-child {
    grid-column: 1/-1;
  }
}
.finance-pub .pub__grid > astra-card::part(card) {
  height: 100%;
  box-sizing: border-box;
}
.finance-pub address {
  font-style: normal;
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.finance-pub .pub__sums {
  display: grid;
  gap: var(--space-1);
  justify-items: end;
  margin: var(--space-4) 0 0;
  padding-block-start: var(--space-4);
  border-block-start: 1px solid var(--border-subtle);
}
.finance-pub .pub__sums > div {
  display: flex;
  gap: var(--space-4);
  align-items: baseline;
}
.finance-pub .pub__sums dt {
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.finance-pub .pub__sums dd {
  margin: 0;
  min-width: 7rem;
  text-align: end;
  font-variant-numeric: tabular-nums;
}
.finance-pub .pub__sums .is-total dt {
  color: var(--text-primary);
  font-weight: var(--weight-medium);
}
.finance-pub .pub__sums .is-total dd {
  font-weight: var(--weight-semibold);
  font-size: var(--text-lg);
}
.finance-pub .pub__methods + .kv-list {
  margin-block-start: var(--space-3);
}
.finance-pub .pub__message {
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.finance-pub .pub__foot {
  color: var(--text-tertiary);
  font-size: var(--text-sm);
  text-align: center;
}
.finance-pub .pub__pay {
  display: grid;
  gap: var(--space-4);
}
.finance-pub .pub__pay-lede {
  margin: 0;
  color: var(--text-secondary);
}
.finance-pub .pub__pay-lede strong {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}
.finance-pub .pub__pay-form {
  display: grid;
  gap: var(--space-4);
}
.finance-pub .pub__pay-form[hidden] {
  display: none;
}
.finance-pub #payment-element {
  min-height: 3rem;
}
.finance-pub .pub__pay-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}
.finance-pub .pub__pay-msg {
  display: none;
  align-items: flex-start;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
  color: var(--text-primary);
}
.finance-pub .pub__pay-msg.is-shown {
  display: flex;
}
.finance-pub .pub__pay-msg astra-icon {
  flex: none;
  margin-block-start: var(--status-icon-nudge);
}
.finance-pub .pub__pay-msg.is-error {
  background: var(--danger-50);
  color: var(--danger-700);
}
.finance-pub .pub__pay-msg.is-success {
  background: var(--success-50);
  color: var(--success-700);
}
.finance-pub .pub__pending {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  margin: 0;
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--success-50);
  color: var(--success-700);
}
.finance-pub .pub__pending astra-icon {
  flex: none;
  margin-block-start: var(--status-icon-nudge);
}
.finance-pub .pub__pending p {
  margin: 0;
}
.finance-pub .pub__pending p + p {
  margin-block-start: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--text-sm);
}
.finance-pub .pub__alt {
  margin: 0;
}
.finance-pub .pub__alt summary {
  cursor: pointer;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  border-radius: var(--radius-sm);
}
.finance-pub .pub__alt summary:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
.finance-pub .pub__alt[open] summary {
  margin-block-end: var(--space-3);
}

.finance-media {
  position: relative;
  min-height: 60vh;
  /* THE CONTROL BLOCK IS A STACK, NOT A ROW. The view switch sits ON TOP of the type
           filter because the two answer different questions in sequence — WHICH library, then
           narrowed to WHICH type. Laid side by side (what this row used to do) they read as
           peers, and peers is exactly the lie: the switch changes the subject, the chips only
           qualify it. Stacking is also what every other console here does with astra-tabs
           (shop-orders, xtra-articles, the support inbox): tabs above the tools they scope. */
}
.finance-media .media__controls {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-3, 0.75rem);
}
.finance-media {
  /* Both halves withdrawn (no bin, one kind): the block draws nothing and leaves no gap. */
}
.finance-media .media__controls:not(:has(> :not([hidden]))) {
  display: none;
}
.finance-media .media__chips {
  display: flex;
  gap: var(--space-2, 0.5rem);
  flex-wrap: wrap;
}
.finance-media {
  /* The type filter wears the portal's filter-chip look (_portal-patterns.scss
     .filter-chips): a quiet pill, the pressed one tinted with accent ink, never a solid
     accent fill (a solid fill beside the view tabs read as a second selection). */
}
.finance-media .chip {
  appearance: none;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1-5, 0.375rem);
  min-height: 2rem;
  padding: var(--space-1) var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-pill);
  background: var(--surface-raised);
  color: var(--text-secondary);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--motion-hover), border-color var(--motion-hover), color var(--motion-hover);
}
.finance-media .chip:hover {
  border-color: var(--border-default);
  color: var(--text-primary);
}
.finance-media .chip[aria-pressed=true] {
  background: color-mix(in srgb, var(--accent-500) 10%, var(--surface-raised));
  border-color: color-mix(in oklab, var(--accent-500) 40%, transparent);
  color: var(--accent-ink);
}
.finance-media .chip:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
@media (max-width: 767.98px) {
  .finance-media {
    /* MEASURED at 375px: the pill is 34.3px tall — under the 44px touch floor, and it
             always has been, on both libraries. Raised on the part rather than in the base
             rule so a desktop control row keeps its compact pills, which is the same trade
             `.media__selbar astra-button` and `.card__restore` already make in this sheet. */
  }
  .finance-media .chip {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}
.finance-media {
  /* …AND THE FLOOR IS A FACT ABOUT THE POINTER, NOT THE VIEWPORT. `max-width: 767.98px`
           misses an iPad in portrait by 0.02px: MEASURED at 768×1024 the chips came back
           34.3px with a thumb on them, and every touch tablet above that width is the same
           miss. Raised again on the query this sheet already uses for the only other tap
           target it has to defend (`.usage__badges astra-button`), purely additively — a
           fine pointer at any width still gets the compact pill. The three controls move
           together because a phone that gets 44px chips and a 32px Restore is the same
           inconsistency one breakpoint further out. */
}
@media (pointer: coarse) {
  .finance-media .chip {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .finance-media .media__selbar astra-button {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .finance-media .media__selbar astra-button::part(button) {
    min-height: 44px;
  }
  .finance-media .card__restore {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .finance-media .card__restore::part(button) {
    min-height: 44px;
  }
}
.finance-media {
  /* ── Selection bar ─────────────────────────────────────────────────
     A TINTED SURFACE WITH A LEADING ICON (the toast idiom), never an accent stripe down one
     edge — the platform rule. It replaces the type chips while selecting, so the two never
     compete for the same row. */
}
.finance-media .media__selbar {
  display: flex;
  align-items: center;
  gap: var(--space-3, 0.75rem);
  flex-wrap: wrap;
}
.finance-media .media__selbar[hidden] {
  display: none;
}
.finance-media {
  /* The chips are hidden from the a11y tree by their own `hidden` (that is the script's job),
     but a zero-height flex ROW still earns the column gap either side of itself — dead space
     where the chips used to be. So the WRAPPER collapses with them, exactly as the portal's
     library does; the two media pages differ in no element and no rule. */
}
.finance-media .media__selbar .status-surface__actions {
  margin-inline-start: auto;
}
.finance-media {
  /* ── Grid ─────────────────────────────────────────────────────────── */
}
.finance-media .media__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--space-4, 1rem);
}
@media (max-width: 560px) {
  .finance-media .media__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-3, 0.75rem);
  }
  .finance-media {
    /* Audio keeps its square here now: the tile variant is a cover with a disc — the same
       shape as a video card — and works at a 2-up 151.5px exactly like one, so the old
       full-width-row exception (and its hidden AUDIO badge) went with the transport row
       that needed it. The disc's own mobile step-down rides the shared block below. */
  }
}
.finance-media .card {
  position: relative;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg, 12px);
  background: var(--surface-raised);
  overflow: hidden;
  cursor: pointer;
  transition: transform var(--motion-hover), box-shadow var(--motion-hover), border-color var(--motion-hover);
}
.finance-media .card:hover {
  box-shadow: var(--elevation-2);
  border-color: var(--border-default);
}
.finance-media {
  /* The lift is motion, so it waits for permission: with motion reduced the card still
     answers the pointer (shadow + border), it just does not move. */
}
@media (prefers-reduced-motion: no-preference) {
  .finance-media .card:hover {
    transform: translateY(-3px);
  }
}
.finance-media .card:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
.finance-media .card__media {
  position: relative;
  aspect-ratio: 1/1;
  background: var(--surface-sunken);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.finance-media .card__media img, .finance-media .card__media video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.finance-media .card__tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2, 0.5rem);
  width: 100%;
  height: 100%;
  padding: var(--space-2, 0.5rem);
  color: var(--text-tertiary);
  background: linear-gradient(135deg, var(--surface-sunken), var(--surface-raised));
}
.finance-media {
  /* The document tile's second line — format + weight, so a card with no picture still says
     what the file IS. Secondary ink, because the card body underneath carries the name. */
}
.finance-media .card__tile-label {
  font-size: var(--text-xs, 0.75rem);
  color: var(--text-secondary);
  letter-spacing: 0.02em;
  text-align: center;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.finance-media {
  /* In-card audio IS the DS tile: astra-audio's `variant="tile"` carries the whole design
     (cover-first stage, centred scrim disc, bottom-edge scrub rail, designed no-cover
     ground), so no ::part surgery remains — the card only sizes the disc through the two
     custom properties astra-audio publishes for exactly this job. The disc step matches
     `.card__play`'s 2.5rem, and the ≤560px block below steps both down together. One player
     at a time is the DS's shared MediaRegistry claim — never reimplemented here.

     THE TILE'S BOTTOM INLINE-END CORNER IS THE PLAYER'S, and this sheet must keep it free.
     astra-audio/astra-video now paint their own running time there once a tile has been
     played — a small glass pill above the scrub rail, reading "0:12 / 3:41" (and "0:12 / —"
     while the length is genuinely unknown). It is the DS's, inside the shadow root, and it
     takes no attribute and no property from this page; the page's only duty is not to park
     anything on top of it. Which is why every overlay this sheet owns sits along the TOP
     edge — the kind chip inline-start, the licence flag and the selection checkbox
     inline-end — and why a future overlay must go there too, not into the corner opposite.
     The kind line beneath the picture prints the same length from the STORED durationMs, so
     formatDuration() floors exactly as the DS clock does: two readings of one file, a few
     pixels apart, must not disagree. */
}
.finance-media .card__audio {
  width: 100%;
  height: 100%;
  --aud-play-size: 2.5rem;
  --aud-play-icon: var(--icon-size-md);
}
.finance-media {
  /* In-card video is the SAME DS tile family — astra-video's `variant="tile"` — sized the
     same way through astra-video's own published properties. The ROUNDING is the CARD's:
     .card is `border-radius: 12px` + `overflow: hidden` and .card__media clips too, so the
     square's top corners are cut by the card, not by the player (measured: the host, .vid
     and .vid__stage all compute to 0px here, because this sheet sets no radius on
     .card__video). The DS's host → .vid → stage `inherit` chain is still real and still
     worth knowing about — it is what would carry a radius INTO the shadow root if a host
     ever set one — it is simply not the mechanism doing the work on this page. */
}
.finance-media .card__video {
  width: 100%;
  height: 100%;
  --vid-play-size: 2.5rem;
  --vid-play-icon: var(--icon-size-md);
}
.finance-media {
  /* Deliberately theme-INDEPENDENT: this scrim floats over the video frame itself, not over a
     themed surface, so it stays a dark disc with a white glyph in both themes. */
}
.finance-media .card__play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  color: #fff;
}
.finance-media {
  /* 2.5rem is astra-button's icon-only `md` footprint — the DS's own answer to "a round
     control with a 20px glyph in it". */
}
.finance-media .card__play span {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(2px);
}
.finance-media .card__body {
  display: flex;
  align-items: center;
  gap: var(--space-2, 0.5rem);
  padding: var(--space-3, 0.75rem) var(--space-3, 0.75rem);
}
.finance-media .card__meta {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.finance-media .card__name {
  font-size: var(--text-sm, 0.875rem);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.finance-media .card__kind {
  font-size: var(--text-xs, 0.75rem);
  color: var(--text-tertiary);
}
.finance-media .card__menu-btn {
  flex: 0 0 auto;
}
.finance-media .card__badge {
  position: absolute;
  top: 0.5rem;
  left: 0.5rem;
}
.finance-media {
  /* The §13.6 licence flag floats opposite the kind chip so the two never overlap. */
  /* Selection: the checkbox only exists while selecting, and a picked card carries the accent
     ring so the state survives on a tile whose picture is mostly white. */
}
.finance-media .card__pick {
  position: absolute;
  top: 0.375rem;
  right: 0.375rem;
  z-index: 2;
  display: none;
}
.finance-media.is-selecting .card__pick {
  display: block;
}
.finance-media.is-selecting .card__menu-btn {
  visibility: hidden;
}
.finance-media {
  /* …and the licence flag steps down out of the checkbox's corner for exactly as long as the
     checkbox is there, rather than being displaced permanently for a mode that is usually
     off — which left every licensed tile's flag misaligned with the kind chip opposite it. */
  /* WHILE SELECTING, THE TILE IS THE PICK — for AV squares too. The in-card players eat
     clicks by design (stopPropagation, so scrubbing never opens the drawer); this hands
     the pointer back to the card for the mode's duration, so a press picks instead of
     playing. */
}
.finance-media.is-selecting .card__media astra-audio, .finance-media.is-selecting .card__media astra-video {
  pointer-events: none;
}
.finance-media .card.is-picked {
  border-color: var(--accent-500);
  box-shadow: 0 0 0 2px var(--accent-500) inset;
}
.finance-media {
  /* ── "Recently deleted" (MEDIA_INFRA_SPEC.md §5) ───────────────────
           A TABLIST, NOT A PILL. This used to be a `.chip` in its own group beside the type
           chips, and that was the bug the owner reported: `.chip[aria-pressed="true"]` paints
           the accent fill, so with the bin open BOTH "All" and "Recently deleted" were filled
           accent at once — two things selected, in one visual language, answering two
           different questions. Measured: 2 accent-filled pills at 375px AND at 1280px.

           astra-tabs is the platform's answer to "which view am I in" (the support inbox,
           shop-orders, xtra-articles, pixel-content all use it), and it fixes the ambiguity
           three ways at once:
             • a tablist has a MANDATORY selection, so "Library" becomes a real, visible,
               pressable state instead of being signalled only by the absence of a fill;
             • the UNDERLINE variant marks the active tab with accent TEXT + a 2px indicator,
               which is a different mark from a filled pill — so the switch can never be
               mistaken for a peer of the chips. `the pill variant` was rejected for exactly
               this reason: its selected tab is `background: var(--fill-accent)`, i.e. the
               same accent-filled pill, which would have rebuilt the bug in a new element;
             • an astra-tab host is `min-height: 2.75rem` = 44px exactly, clearing the touch
               floor that the 34.3px pill never did (the pill variant is 2rem = 32px).

           THE TYPE CHIPS STAY, AND STAY OPERABLE, IN BOTH VIEWS — they are not decoration
           here. `/api/media/recently-deleted` takes `type` and honours it all the way down
           (MediaController::recentlyDeleted → EngineLibrary::deletedShapes →
           AssetLibrary::recentlyDeletedForOwner($owner, $search, $kind, …) → the DAO's
           pageDeletedForOwner/countDeletedForOwner), and this page has always put `type` in
           that request's query string. Filtering a full bin down to Documents is a real need,
           so the chips are left live rather than hidden: hiding a filter that works would
           trade one lie for another. */
}
.finance-media .media__views {
  min-width: 0;
}
.finance-media {
  /* THIS STRIP HAS NO PANELS. The grid below is the panel — it is outside the component
           because it is also the drop target, the selection surface and the paging container,
           and moving it inside an astra-tab-panel would put all of that behind a slot for no
           gain. astra-tabs still renders its empty `.tabs__panels` with a `--space-4`
           padding-block-start, which MEASURED as 16px of dead air between the switch and the
           type chips (244.2 → 272.2 at 375px) and read as a gap twice the size of the one the
           control block actually asks for. Collapsed through the exposed part. */
}
.finance-media .media__views::part(panels) {
  display: none;
}
.finance-media {
  /* A deleted file is desaturated so the grid reads at a glance as a DIFFERENT place rather
     than the library with extra buttons. Never colour alone: every card also carries the
     strip below, in words. */
}
.finance-media .card--deleted .card__media {
  filter: grayscale(1);
  opacity: 0.7;
}
.finance-media {
  /* …and the desaturation LIFTS while a trash preview is actually playing — colour returns
     when the operator looks. `data-started` is the DS players' own reflected first-playing
     fact (set on first `playing`, cleared on track change/registry reset), so the lift can
     never key on a guess. It is also the attribute the DS reveals the tile's scrub rail AND
     its corner time pill on, so all three arrive as ONE event: the card colours, the rail
     appears, the clock starts reading. Keying the lift on anything else would stagger them. */
}
.finance-media .card--deleted .card__media:has(astra-video[data-started]),
.finance-media .card--deleted .card__media:has(astra-audio[data-started]) {
  filter: none;
  opacity: 1;
}
.finance-media {
  /* THE ROW'S STATE, IN THE TOAST IDIOM — tinted surface + leading glyph + a sentence, never
     a start-edge stripe. `--over` is the row whose 30 days ran out or whose stored file has
     already gone: it carries the reason and NO restore control, because a button that could
     only ever return a refusal is the defect this surface exists to end. */
  /* THE STRIP MUST WRAP, NOT CRUSH. `.media__grid` tracks are `minmax(180px, 1fr)`, so a
           card can be 180px wide — about 156px inside this padding. Take the clock glyph, two
           gaps and a `size="sm"` Restore button out of that and the sentence was left roughly
           40px, which it spent one word per line ("30 / days / left / to / restore"). The
           button is `flex: 0 0 auto`, so it never yields; only the text could, and `min-width:
           0` let it yield all the way down. Fixed at both ends: the label asks for a real
           basis (below) so the BUTTON wraps to its own line before the sentence breaks up,
           and the sentence itself lost the words the Restore button beside it already says. */
}
.finance-media .card__life {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2, 0.5rem);
  padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
  font-size: var(--text-xs, 0.75rem);
}
.finance-media .card__life--ok {
  background: var(--surface-sunken);
  color: var(--text-secondary);
}
.finance-media .card__life--over {
  background: var(--surface-sunken);
  color: var(--text-tertiary);
}
.finance-media .card__life p {
  margin: 0;
  min-width: 0;
  flex: 1 1 6rem;
}
.finance-media .card__life astra-icon {
  flex: 0 0 auto;
}
.finance-media .card__restore {
  flex: 0 0 auto;
  margin-inline-start: auto;
}
@media (max-width: 560px) {
  .finance-media {
    /* A 2-up tile is 153.5px wide, and the glyph, the sentence and the button cannot share
       one line inside it: `flex: 0 0 auto` on the button squeezed the paragraph to ZERO
       width and then painted the button ON TOP of the words, so "29 days left to restore"
       was unreadable on a phone. The strip becomes a grid instead — glyph, then the
       sentence in a `minmax(0, 1fr)` track, then the ONE action a deleted card offers on
       its own row, which is also where it clears the 44px touch floor that `sm` does not
       reach on its own (it stays compact in a desktop grid tile). */
  }
  .finance-media .card__life {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: start;
    row-gap: var(--space-2, 0.5rem);
  }
  .finance-media .card__life p {
    grid-column: 2;
  }
  .finance-media .card__restore {
    grid-column: 1/-1;
    justify-self: start;
    margin-inline-start: 0;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .finance-media .card__restore::part(button) {
    min-height: 44px;
  }
}
.finance-media {
  /* One step down the DS scale on a phone, where a 2-up tile is 151.5px and every glyph on it
     costs proportionally more. AFTER the rules it overrides: identical specificity, so source
     order is the only thing that decides. */
}
@media (max-width: 560px) {
  .finance-media .card__play span {
    width: 2rem;
    height: 2rem;
  }
  .finance-media .card__play astra-icon {
    --icon-size-md: var(--icon-size-sm);
  }
  .finance-media .card__audio {
    --aud-play-size: 2rem;
    --aud-play-icon: var(--icon-size-sm);
  }
  .finance-media .card__video {
    --vid-play-size: 2rem;
    --vid-play-icon: var(--icon-size-sm);
  }
}
.finance-media {
  /* Uploading / failed / loading states — none of them are pressable, so they drop the card's
     affordances entirely rather than inviting a click that does nothing. */
}
.finance-media .card--pending, .finance-media .card--skeleton {
  cursor: default;
}
.finance-media .card--pending:hover, .finance-media .card--skeleton:hover {
  transform: none;
  box-shadow: none;
  border-color: var(--border-subtle);
}
.finance-media .card--skeleton {
  pointer-events: none;
}
.finance-media {
  /* Tone follows the surface underneath: sunken on the raised card body, one step further to
     --surface-page on the tile, which is itself sunken — a skeleton painted in its host's own
     colour is invisible. */
}
.finance-media .card--skeleton astra-skeleton {
  --sk-bg: var(--surface-sunken);
}
.finance-media .card--skeleton .card__media astra-skeleton {
  width: 100%;
  --sk-bg: var(--surface-page);
}
.finance-media {
  /* A cover that has not decoded yet — the FIRST-PAINT case. Absolutely positioned inside the
     square the tile already reserves, so it can never move anything; removed the moment the
     image loads (or fails). */
}
.finance-media .card__ph {
  position: absolute;
  inset: 0;
  width: 100%;
  --sk-bg: var(--surface-page);
}
.finance-media {
  /* The tone underlay: an asset with a STORED dominant colour paints its own colour while
     its cover decodes — the picture's first pixel is a fact about the picture, not a generic
     shimmer. No animation, so there is nothing to reduce for reduced-motion; the skeleton
     stays the fallback for rows without a stored colour. */
}
.finance-media .card__ph--tone {
  position: absolute;
  inset: 0;
}
.finance-media .card__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2, 0.5rem);
  padding: var(--space-3, 0.75rem);
  text-align: center;
  background: color-mix(in oklch, var(--surface-raised) 84%, transparent);
  color: var(--text-secondary);
}
.finance-media .card__overlay astra-progress-bar {
  width: 80%;
}
.finance-media .card__error {
  color: var(--danger-700);
  font-size: var(--text-sm, 0.8125rem);
}
.finance-media .media__more {
  display: flex;
  justify-content: center;
  padding: var(--space-3, 0.75rem) 0;
}
.finance-media {
  /* ── Edit drawer ──────────────────────────────────────────────────── */
}
.finance-media #edit-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4, 1rem);
}
.finance-media {
  /* ONE UNIT: the asset. The thing that plays and the facts about the file it plays are the
     same object — as two separately bordered boxes they read as two. */
}
.finance-media .drawer__asset {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md, 10px);
  background: var(--surface-sunken);
  overflow: hidden;
}
.finance-media .drawer__preview {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  max-height: 42vh;
  min-height: 8rem;
}
.finance-media .drawer__preview img {
  max-width: 100%;
  max-height: 42vh;
  object-fit: contain;
  display: block;
}
.finance-media .drawer__preview--player {
  overflow: visible;
  max-height: none;
  min-height: 0;
  display: block;
  padding: var(--space-3, 0.75rem);
}
.finance-media .drawer__preview--player > astra-audio, .finance-media .drawer__preview--player > astra-video {
  display: block;
  width: 100%;
}
.finance-media .drawer__preview--player > astra-audio::part(root) {
  background: transparent;
  border: 0;
  padding: 0;
}
.finance-media .drawer__preview--player > astra-audio::part(info) {
  display: none;
}
.finance-media .drawer__readonly {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2, 0.5rem) var(--space-4, 1rem);
  padding: var(--space-3, 0.75rem);
  border-block-start: 1px solid var(--border-subtle);
  font-size: var(--text-sm, 0.8125rem);
  color: var(--text-secondary);
}
.finance-media .drawer__readonly code {
  font-family: var(--font-mono, monospace);
  color: var(--text-primary);
}
.finance-media {
  /* ── The palette row (stored colour facts, made copyable) ─────────────
     A plain plate row like `.drawer__readonly` — no box, no stripe. Each swatch is a real
     button whose press copies the hex, and the hex is ALSO printed in the open underneath,
     because a value hidden behind hover is not "displayed". */
}
.finance-media .drawer__palette {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3, 0.75rem);
  padding: var(--space-3, 0.75rem);
  border-block-start: 1px solid var(--border-subtle);
}
.finance-media .drawer__swatch {
  position: relative;
  display: grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 0;
  cursor: pointer;
  border-radius: var(--radius-sm, 6px);
  background: var(--swatch);
  /* hairline derived from the stored ink so a near-white swatch still reads on the
     plate; the fallback only ever chromes a synthesised dominant chip with no stored
     ink — it never claims contrast ON the swatch. */
  box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--swatch-ink, var(--text-primary)) 18%, transparent);
}
.finance-media .drawer__swatch--dominant {
  width: 2.75rem;
  height: 2.75rem;
}
.finance-media .drawer__swatch astra-icon {
  color: var(--swatch-ink, var(--text-primary));
  opacity: 0;
  transition: opacity var(--motion-hover);
}
.finance-media .drawer__swatch:hover astra-icon, .finance-media .drawer__swatch:focus-visible astra-icon {
  opacity: 1;
}
.finance-media .drawer__swatch:focus-visible {
  outline: 2px solid var(--accent-500);
  outline-offset: 2px;
}
.finance-media .drawer__swatch-col {
  display: block;
}
.finance-media .drawer__swatch-hex {
  display: block;
  margin-block-start: var(--space-1, 0.25rem);
  text-align: center;
  font-family: var(--font-mono, monospace);
  font-size: var(--text-3xs, 0.625rem);
  color: var(--text-tertiary);
}
.finance-media {
  /* 44px floor on touch — the ::after strip idiom, never a bigger visible chip. */
}
@media (pointer: coarse) {
  .finance-media .drawer__swatch::after {
    content: "";
    position: absolute;
    inset: 50% auto auto 50%;
    translate: -50% -50%;
    width: max(100%, 44px);
    height: max(100%, 44px);
  }
}
.finance-media {
  /* The cover's own state, on the asset plate it belongs to. `--quiet` because this is a row
     GROUPED with the file facts above it, and `--status-surface-base` because the plate is
     sunken — the utility composites its tint over whatever surface it is told it is on. */
}
.finance-media .drawer__cover {
  border-block-start: 1px solid var(--border-subtle);
  --status-surface-base: var(--surface-sunken);
}
.finance-media {
  /* The callout is a ROW of the plate, not a card inside a card: the quiet tint stays, the
     box chrome goes, and the row gets the plate's own rhythm. (The chrome used to be
     stripped on the WRAPPER above, where both declarations were no-ops — the surface inside
     kept core.css's border + radius and read as a cramped box nested flush in the plate.) */
}
.finance-media .drawer__cover > .status-surface {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: var(--space-3, 0.75rem);
}
.finance-media .drawer__cover-thumb {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: var(--radius-sm, 4px);
  object-fit: cover;
  display: block;
  background: var(--surface-sunken);
}
.finance-media {
  /* ── "Where this file is used" worklist (the §5 refusal) ───────────
     Moved from media.php's last <style> block (2026-10-28; a template carries no rules).
     Ported rule for rule from apps/portal/templates/content.php so the two halves of the
     platform paint one dialog, not two dialects. MediaBulkDeleteTemplateTest reads these
     rules from this partial.
     `minmax(0, 1fr)` on every track here is load-bearing rather than tidy: a stored media
     name — and a post title — is routinely ONE unbroken token and a `1fr` track's min is
     `auto`, so a single 60-character name widens the dialog and scrolls the panel sideways at
     375px. This estate has shipped that exact bug. */
}
.finance-media #usage-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4, 1rem);
}
.finance-media #usage-note .status-surface__message {
  overflow-wrap: anywhere;
}
.finance-media .usage__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2, 0.5rem);
}
.finance-media {
  /* A BULK refusal holds several blocked files at once, so the SAME rows are grouped under
     the file they belong to. This is a heading plus a nested list — the rows themselves are
     still built by `usageRow`, there is no second row renderer, and a single blocked file
     never reaches this shell at all (it opens the ungrouped single-file worklist instead). */
}
.finance-media .usage__group {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-2, 0.5rem);
}
.finance-media .usage__group-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  min-width: 0;
  gap: var(--space-1, 0.25rem) var(--space-2, 0.5rem);
  padding-block-start: var(--space-2, 0.5rem);
}
.finance-media .usage__group-name {
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: var(--weight-semibold, 600);
}
.finance-media .usage__group-count {
  font-size: var(--text-sm, 0.8125rem);
  color: var(--text-secondary);
}
.finance-media {
  /* SUNKEN, like the drawer's asset plate — `--surface-raised` is the modal panel's own
     colour in the light theme, which would leave the rows separated by a hairline alone. */
}
.finance-media .usage__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--space-1, 0.25rem) var(--space-3, 0.75rem);
  min-height: 2.75rem;
  padding: var(--space-3, 0.75rem);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md, 10px);
  background: var(--surface-sunken);
}
.finance-media .usage__row > astra-icon {
  color: var(--text-secondary);
  margin-block-start: var(--status-icon-nudge);
}
.finance-media .usage__body {
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-1, 0.25rem);
}
.finance-media {
  /* Long titles wrap INSIDE the track rather than widening it — `anywhere` because a stored
     title can be a single unbroken token (a slug, a filename, an external URL). */
}
.finance-media .usage__name {
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: var(--weight-medium, 500);
}
.finance-media {
  /* The plain-text half of the rule "never offer a link that answers 403/404": a row the
     server did not prove openable is body ink, with no anchor and no pointer affordance. */
}
.finance-media .usage__name--plain {
  color: var(--text-primary);
}
.finance-media .usage__name astra-icon {
  margin-inline-start: var(--space-1, 0.25rem);
  vertical-align: -0.125em;
}
.finance-media .usage__meta {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: var(--text-sm, 0.8125rem);
  color: var(--text-secondary);
}
.finance-media .usage__ref {
  font-family: var(--font-mono, monospace);
  font-size: var(--text-xs, 0.75rem);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.finance-media {
  /* Badges AND the one action a stale row offers share this cell — the row's third grid
     track — so the clear control never needs a track of its own (which would change
     `.usage__row`'s pinned `auto minmax(0, 1fr) auto` and squeeze the title). */
}
.finance-media .usage__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1, 0.25rem);
}
.finance-media {
  /* TOUCH HIT AREA. The DS's `sm` button is 2rem tall — right beside a badge with a mouse,
     under the 44px minimum with a thumb, and Clear is the only tap target inside a row. The
     HOST grows, so the extra area belongs to the element the listener is bound to. */
}
@media (pointer: coarse), (max-width: 560px) {
  .finance-media .usage__badges astra-button {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .finance-media .usage__badges astra-button::part(button) {
    min-height: 44px;
  }
}
@media (max-width: 560px) {
  .finance-media {
    /* The badges drop off the row's trailing edge onto their own line under the text, so
       the body column keeps its width instead of being squeezed to a word. */
  }
  .finance-media .usage__row {
    grid-template-columns: auto minmax(0, 1fr);
  }
  .finance-media .usage__badges {
    grid-column: 2;
  }
}
.finance-media {
  /* ── Select-mode pins (moved with the worklist) ──────────────────────
     After `.card__badge` above, so the licence flag's own offset wins at equal specificity.
     THE LICENCE FLAG MOVES FOR THE CHECKBOX, AND ONLY FOR AS LONG AS IT IS THERE. */
}
.finance-media .card__badge--license {
  left: auto;
  right: 0.5rem;
}
.finance-media.is-selecting .card__badge--license {
  top: 2.4rem;
}
.finance-media.is-selecting .media__controls {
  display: none;
}
@media (max-width: 560px) {
  .finance-media {
    /* These two are the ONLY way out of the mode and the only way to run the delete, and
       the DS's `sm` is 32px — under the 44px floor. The size attribute keeps the bar
       compact on a desktop row; the tap target is raised on the part instead. */
  }
  .finance-media .media__selbar astra-button {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  .finance-media .media__selbar astra-button::part(button) {
    min-height: 44px;
  }
}

/* ── Drop zone, scoped to the shell's MAIN region ─────────────────────
   It lives OUTSIDE the shell (see its markup comment): `.sh__main` carries a mask, and a
   mask clips its whole painted subtree — `position: fixed` descendants included — so a frame
   that has to outline the main region cannot live inside it. */
.finance-media__dropzone {
  position: fixed;
  z-index: 40;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  /* border-box, so the width the script computes IS the painted width. */
  box-sizing: border-box;
  border: 3px dashed var(--accent-500);
  border-radius: var(--radius-lg, 16px);
  background: color-mix(in oklch, var(--accent-500) 8%, transparent);
}

.finance-media__dropzone[hidden] {
  display: none;
}

.finance-media__dropzone-pill {
  padding: var(--space-3, 0.75rem) var(--space-5, 1.25rem);
  border-radius: 999px;
  background: var(--accent-500);
  color: var(--text-on-accent);
  font-weight: 600;
  box-shadow: var(--elevation-3);
}

.finance-stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-stack);
  min-width: 0;
}

.finance-consequences {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
}
.finance-consequences > li {
  display: grid;
  grid-template-columns: 1.25rem minmax(0, 1fr);
  gap: var(--space-3);
  align-items: start;
  font-size: var(--text-sm);
  color: var(--text-secondary);
}
.finance-consequences > li > astra-icon {
  width: 1.25rem;
  height: 1.25rem;
  color: var(--text-tertiary);
}
.finance-consequences > li[data-tone=warning] {
  color: var(--text-primary);
}
.finance-consequences > li[data-tone=warning] > astra-icon {
  color: var(--warning-ink);
}
.finance-consequences strong {
  color: var(--text-primary);
  font-weight: var(--weight-semibold);
}

.review-layout {
  --review-layout-aside: 22rem;
  --review-layout-gap: var(--space-layout-sm);
  --review-layout-sticky-top: var(--space-4);
  --review-layout-chrome: 96px;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--review-layout-gap);
  align-items: start;
}

.review-layout > * {
  min-inline-size: 0;
}

.review-layout__main,
.review-layout__aside {
  display: flex;
  flex-direction: column;
  gap: var(--space-stack-lg);
}

.review-layout__main > *,
.review-layout__aside > * {
  flex-shrink: 0;
}

@media (min-width: 1024px) {
  .review-layout {
    grid-template-columns: minmax(0, 1fr) var(--review-layout-aside);
  }
  .review-layout__aside {
    box-sizing: border-box;
    position: sticky;
    top: calc(var(--review-layout-sticky-top) - var(--sh-main-pad-block-start, 0px));
    max-block-size: calc(100dvh - var(--review-layout-chrome) - 2 * var(--review-layout-sticky-top));
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-block-end: var(--space-1);
  }
}
:root {
  /* HOW LONG THE HOLD LASTS BEFORE THE PAGE GIVES UP AND SHOWS EVERYTHING.
     Not 3s-because-it-was-3s: measured. On the estate's own pages the module
     graph resolves in ~600ms on a warm desktop connection and 15.2s on Slow 4G,
     so no single number both "never fires on a good load" and "fires quickly on
     a broken one". Any number at all is only safe because the revealed state is
     now a labelled, correctly-laid-out page rather than a text dump — see the
     header. Measured at 4s, the reveal landed 7.4s into a 15.5s load and the
     operator lost the "this is loading" reading of the skeleton, getting a page
     that looked finished and empty for the eight seconds that followed. 8s keeps
     the skeleton through the first half of a genuinely slow load, never fires at
     all on a warm one, and still puts a page whose script is never coming in
     front of a reader inside eight seconds. */
  --astra-pre-upgrade-reveal: 8s;
  /* THE SECOND TIMER, AND WHY THERE ARE TWO. Putting a control's label back
     inside a box that was already reserved moves nothing (measured: 0.0001 of
     layout shift). Putting the SHELL CHROME back does — the nav is in normal
     flow, so revealing it pushes the page down 268px, which on a slow-but-working
     load would be a large shift for nothing, since the shell was going to arrive
     a few seconds later and place it properly anyway. So the chrome and the
     hidden tab panels — everything whose reveal costs the reader a jump — waits
     on a second, deliberately pessimistic timer.
     20s is chosen against the measurement rather than by feel: the slowest
     upgrade on the estate's own pages was 16,409ms with core.css applying at
     ~2,700ms, so anything under ~13.7s fires on a load that was going to succeed.
     Waiting is nearly free here: the page's own content is readable throughout,
     and only inert chrome and the non-first tab panels are behind this timer. */
  --astra-pre-upgrade-chrome-reveal: 20s;
  /* The plate the held controls paint. --surface-sunken is one step down from
     the page in light (neutral-100 on neutral-50) and one step up in dark
     (a well over neutral-900), so the placeholder reads as a recess in BOTH
     themes and can never come out page-on-page. */
  --astra-pre-upgrade-plate: var(--surface-sunken);
}

@keyframes astra-pre-upgrade-reveal {
  to {
    color: inherit;
    background: none;
  }
}
@keyframes astra-pre-upgrade-restore {
  to {
    max-height: none;
    content-visibility: visible;
    color: inherit;
    background: none;
  }
}
@keyframes astra-pre-upgrade-retire {
  to {
    opacity: 0;
  }
}
astra-shell-admin:not(:defined), astra-shell-ninefive:not(:defined), astra-shell-partner:not(:defined), astra-shell-identity:not(:defined), astra-shell-invoice:not(:defined), astra-shell-auth:not(:defined) {
  display: block;
  position: relative;
  box-sizing: border-box;
  min-height: 100dvh;
  background: var(--surface-page);
  color: var(--text-primary);
}

astra-shell-admin:not(:defined), astra-shell-ninefive:not(:defined), astra-shell-partner:not(:defined), astra-shell-identity:not(:defined) {
  /* 12 frame + 60 topbar + 12 gap, then the page gutter .sh__main applies. */
  padding: calc(84px + var(--gutter)) calc(12px + var(--gutter));
}

/* The receipt. Measured at 1280px: frame 16px, topbar 16,16 1248x70, main at
   y=102, and the document itself centred at .sh__main's 44rem — a customer-facing
   page whose own sheet is narrower than the window, so centring it here is what
   stops the invoice sliding sideways when the shell arrives. */
astra-shell-invoice:not(:defined) {
  padding: 102px 16px;
}

/* THE PLACEHOLDER AND THE SETTLED PAGE HAVE TO AGREE ON WIDTH, and 44rem is only the
   shell's DEFAULT — `.sh__main` is what a page overrides when its document is wider.
   The public invoice viewer does exactly that (52rem, because it carries a line-items
   table) and the not-found page goes the other way (32rem), and this rule outranks both:
   `astra-shell-invoice:not(:defined) > :not([slot])` is (0,2,1) against a bare class's
   (0,1,0). Measured on one throttled load at 1280px, the bill sat at left=288 w=704 for
   fifteen seconds and then jumped to left=224 w=832 when the shell upgraded — a 128px
   widening and a 64px slide, on the page a customer reads a bill on.
   AND CLS DOES NOT SEE IT. A custom-element upgrade re-slots the light DOM, so the
   layout-instability API scored 0.0001 across that reflow: the instrument that would
   normally catch this is blind to it, which is why the width is published as a property
   the page can state once instead of a number repeated in two places. */
astra-shell-invoice:not(:defined) > :not([slot]) {
  display: block;
  max-width: var(--astra-pre-upgrade-max, 44rem);
  margin-inline: auto;
}

/* THE AUTH SHELL IS NOT A FRAME AND MUST NOT BE GIVEN ONE. It is a two-column
   split — a brand panel beside the form, both full-bleed, no topbar card and no
   rail (measured: the form panel is x=640..1280, y=0..800). A 60px plate across
   the top of a login page is chrome the page does not have, so it is excluded
   from the reservation and from the plates below.
   It gets a reservation of its own instead, because a login page is where every
   session in the estate starts and it loads the same 2.7MB module graph as any
   other page. The numbers are the auth layout's own: two equal columns
   (`minmax(0,1fr) minmax(0,1fr)`), the form column centred both ways at
   `.sh__form-inner`'s 24rem, and the split collapsing at 767.98px — which puts
   the form at x=768 w=384 on a 1280px window, exactly where the shell puts it. */
astra-shell-auth:not(:defined) {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-content: center;
  padding: var(--space-10) var(--space-8);
}

astra-shell-auth:not(:defined) > :not([slot]) {
  width: 100%;
  max-width: 24rem;
  margin-inline: auto;
}

@media (min-width: 768px) {
  astra-shell-auth:not(:defined) {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  astra-shell-auth:not(:defined) > :not([slot]) {
    grid-column: 2;
  }
}
/* THE STACKED SHELLS PUT A NAV STRIP BETWEEN THE TOPBAR AND THE PAGE, and only
   when they were given one. astra-shell-partner's grid is `60px auto 1fr` — the
   `auto` row is the strip, which renders solely when the top-nav slot has
   content (`:host([data-has-nav])`, stamped by the shell on slotchange). The
   same shape carries `tabs` on astra-shell-identity.
   `:has()` reads exactly the condition the shell reads. Measured at 1280px:
   astra-shell-partner without a strip puts main at y=84, with one at y=142 — a
   46px card plus the frame's own 12px gap. Without this rule the payouts and
   dashboard pages travelled 58px on upgrade; with it they do not. */
astra-shell-partner:not(:defined):has(> [slot=top-nav]),
astra-shell-identity:not(:defined):has(> [slot=tabs]) {
  padding-block-start: calc(142px + var(--gutter));
}

/* The two sidebar shells also hold the rail column open. Below 1024px the rail
   becomes a drawer (`@media (max-width: 1023.98px)` in sidebar-shell-base) and
   the reservation goes with it. */
@media (min-width: 1024px) {
  astra-shell-admin:not(:defined),
  astra-shell-ninefive:not(:defined) {
    padding-inline-start: calc(256px + var(--gutter));
  }
}
/* The frame the operator recognises. Two neutral plates on the reserved space,
   so the pre-upgrade page reads as this application loading rather than as a
   document with strange margins. Drawn on the shell's own pseudo-elements: they
   cost no markup, they cannot be reached by a page, and they vanish the instant
   the element upgrades because the selector stops matching. They also retire on
   the failsafe — a permanent grey rail with no nav in it would be a lie. */
astra-shell-admin:not(:defined)::before, astra-shell-ninefive:not(:defined)::before, astra-shell-partner:not(:defined)::before, astra-shell-identity:not(:defined)::before,
astra-shell-admin:not(:defined)::after, astra-shell-ninefive:not(:defined)::after, astra-shell-partner:not(:defined)::after, astra-shell-identity:not(:defined)::after {
  content: "";
  position: absolute;
  background: var(--surface-raised);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-surface);
  /* Retires on the CHROME timer, not the label one: the plates stand in for the
     chrome, so taking them away while the chrome is still held would leave a
     band of nothing where the topbar and rail should be. */
  animation: astra-pre-upgrade-retire 0s var(--astra-pre-upgrade-chrome-reveal) forwards;
}

astra-shell-admin:not(:defined)::before, astra-shell-ninefive:not(:defined)::before, astra-shell-partner:not(:defined)::before, astra-shell-identity:not(:defined)::before {
  inset: 12px 12px auto 12px;
  height: 60px;
}

astra-shell-admin:not(:defined)::after, astra-shell-ninefive:not(:defined)::after, astra-shell-partner:not(:defined)::after, astra-shell-identity:not(:defined)::after {
  /* Rail plate — OFF by default, and `content: none` rather than `width: 0`.
     A zero-width plate is not invisible: its 1px border still paints, which put
     a 2px hairline down the left edge of every stacked shell and of the sidebar
     shells under 1024px, where the rail is a drawer. The two shells that have a
     rail turn it back on below. */
  content: none;
  inset: 84px auto 12px 12px;
}

@media (min-width: 1024px) {
  astra-shell-admin:not(:defined)::after,
  astra-shell-ninefive:not(:defined)::after {
    content: "";
    width: 232px;
  }
}
/* THESE ARE THE ONE GROUP THAT IS NEVER PUT BACK, and that is deliberate rather
   than an oversight. A modal's body, the command palette's field, a dropdown's
   menu items, an <astra-option>, an <astra-table-column> — none of them is
   content an operator is missing. They are UI that has no place on the page until
   something opens it, or a declaration with nothing to read at all; dumping them
   into the middle of the document on a failed load reproduces exactly the text
   soup this file exists to remove. `display: none` with no failsafe is therefore
   the right treatment, and it is safe here because nothing in this list holds a
   sentence the page was trying to tell anyone. */
astra-modal:not(:defined), astra-command-palette:not(:defined), astra-toast-region:not(:defined), astra-toast:not(:defined), astra-tooltip:not(:defined), astra-table-column:not(:defined), astra-option:not(:defined), astra-option-group:not(:defined), astra-menu-item:not(:defined), astra-menu-divider:not(:defined), astra-nav-divider:not(:defined) {
  display: none;
}

astra-button:not(:defined), astra-badge:not(:defined), astra-avatar:not(:defined), astra-switch:not(:defined), astra-checkbox:not(:defined), astra-radio:not(:defined), astra-loading:not(:defined), astra-notification-bell:not(:defined), astra-theme-toggle:not(:defined), astra-workspace-switcher:not(:defined), astra-progress-ring:not(:defined), astra-dropdown:not(:defined), astra-user-menu:not(:defined),
astra-input:not(:defined), astra-textarea:not(:defined), astra-select:not(:defined), astra-combobox:not(:defined), astra-number-input:not(:defined), astra-date-picker:not(:defined), astra-date-range-picker:not(:defined), astra-time-picker:not(:defined), astra-otp-input:not(:defined), astra-tag-input:not(:defined), astra-slider:not(:defined), astra-color-picker:not(:defined), astra-file-upload:not(:defined), astra-media-picker:not(:defined), astra-content-picker:not(:defined), astra-progress-bar:not(:defined),
astra-table:not(:defined), astra-chart:not(:defined), astra-calendar:not(:defined), astra-kanban:not(:defined), astra-chat:not(:defined), astra-audio:not(:defined), astra-audio-trimmer:not(:defined), astra-video:not(:defined), astra-rich-text:not(:defined), astra-batch-progress:not(:defined), astra-batch-review:not(:defined), astra-empty-state:not(:defined), astra-pagination:not(:defined), astra-stats-card:not(:defined), astra-skeleton:not(:defined), astra-notification-item:not(:defined) {
  box-sizing: border-box;
  color: transparent;
  background: var(--astra-pre-upgrade-plate);
  border-radius: var(--radius-control);
  animation: astra-pre-upgrade-reveal 0s var(--astra-pre-upgrade-reveal) forwards;
}

astra-button:not(:defined), astra-badge:not(:defined), astra-avatar:not(:defined), astra-switch:not(:defined), astra-checkbox:not(:defined), astra-radio:not(:defined), astra-loading:not(:defined), astra-notification-bell:not(:defined), astra-theme-toggle:not(:defined), astra-workspace-switcher:not(:defined), astra-progress-ring:not(:defined), astra-dropdown:not(:defined), astra-user-menu:not(:defined) {
  display: inline-block;
  vertical-align: middle;
  min-height: 2.75rem;
  min-width: 2.75rem;
}

/* The widgets are here too, and they were not at first — a reservation is only a
   reservation if the box can take it. `min-height` does not apply to a
   non-replaced INLINE box, and an un-upgraded custom element is inline by
   default, so `astra-empty-state { min-height: 12rem }` did nothing at all on the
   invoice not-found page: 0px where 192px was asked for. It looked correct
   everywhere else purely because `main.page-stack` is a flex container and flex
   blockifies its items. */
astra-input:not(:defined), astra-textarea:not(:defined), astra-select:not(:defined), astra-combobox:not(:defined), astra-number-input:not(:defined), astra-date-picker:not(:defined), astra-date-range-picker:not(:defined), astra-time-picker:not(:defined), astra-otp-input:not(:defined), astra-tag-input:not(:defined), astra-slider:not(:defined), astra-color-picker:not(:defined), astra-file-upload:not(:defined), astra-media-picker:not(:defined), astra-content-picker:not(:defined), astra-progress-bar:not(:defined),
astra-table:not(:defined), astra-chart:not(:defined), astra-calendar:not(:defined), astra-kanban:not(:defined), astra-chat:not(:defined), astra-audio:not(:defined), astra-audio-trimmer:not(:defined), astra-video:not(:defined), astra-rich-text:not(:defined), astra-batch-progress:not(:defined), astra-batch-review:not(:defined), astra-empty-state:not(:defined), astra-pagination:not(:defined), astra-stats-card:not(:defined), astra-skeleton:not(:defined), astra-notification-item:not(:defined) {
  display: block;
  min-height: 2.75rem;
}

/* Sized controls reserve their own height. --control-height is set INSIDE each
   component (astra-input .control--sm etc.), so the ladder is repeated here for
   the one moment the component cannot answer for itself: xs 1.75 / sm 2.25 /
   md 2.75 / lg 3.25rem. A field carrying a `label` also reserves the label row
   above it (--text-sm line + --space-1 gap), which is what stops a labelled form
   from shifting every row down on upgrade. */
astra-button:not(:defined)[size=xs], astra-badge:not(:defined)[size=xs], astra-avatar:not(:defined)[size=xs], astra-switch:not(:defined)[size=xs], astra-checkbox:not(:defined)[size=xs], astra-radio:not(:defined)[size=xs], astra-loading:not(:defined)[size=xs], astra-notification-bell:not(:defined)[size=xs], astra-theme-toggle:not(:defined)[size=xs], astra-workspace-switcher:not(:defined)[size=xs], astra-progress-ring:not(:defined)[size=xs], astra-dropdown:not(:defined)[size=xs], astra-user-menu:not(:defined)[size=xs],
astra-input:not(:defined)[size=xs], astra-textarea:not(:defined)[size=xs], astra-select:not(:defined)[size=xs], astra-combobox:not(:defined)[size=xs], astra-number-input:not(:defined)[size=xs], astra-date-picker:not(:defined)[size=xs], astra-date-range-picker:not(:defined)[size=xs], astra-time-picker:not(:defined)[size=xs], astra-otp-input:not(:defined)[size=xs], astra-tag-input:not(:defined)[size=xs], astra-slider:not(:defined)[size=xs], astra-color-picker:not(:defined)[size=xs], astra-file-upload:not(:defined)[size=xs], astra-media-picker:not(:defined)[size=xs], astra-content-picker:not(:defined)[size=xs], astra-progress-bar:not(:defined)[size=xs] {
  min-height: 1.75rem;
}

astra-button:not(:defined)[size=sm], astra-badge:not(:defined)[size=sm], astra-avatar:not(:defined)[size=sm], astra-switch:not(:defined)[size=sm], astra-checkbox:not(:defined)[size=sm], astra-radio:not(:defined)[size=sm], astra-loading:not(:defined)[size=sm], astra-notification-bell:not(:defined)[size=sm], astra-theme-toggle:not(:defined)[size=sm], astra-workspace-switcher:not(:defined)[size=sm], astra-progress-ring:not(:defined)[size=sm], astra-dropdown:not(:defined)[size=sm], astra-user-menu:not(:defined)[size=sm],
astra-input:not(:defined)[size=sm], astra-textarea:not(:defined)[size=sm], astra-select:not(:defined)[size=sm], astra-combobox:not(:defined)[size=sm], astra-number-input:not(:defined)[size=sm], astra-date-picker:not(:defined)[size=sm], astra-date-range-picker:not(:defined)[size=sm], astra-time-picker:not(:defined)[size=sm], astra-otp-input:not(:defined)[size=sm], astra-tag-input:not(:defined)[size=sm], astra-slider:not(:defined)[size=sm], astra-color-picker:not(:defined)[size=sm], astra-file-upload:not(:defined)[size=sm], astra-media-picker:not(:defined)[size=sm], astra-content-picker:not(:defined)[size=sm], astra-progress-bar:not(:defined)[size=sm] {
  min-height: 2.25rem;
}

astra-button:not(:defined)[size=lg], astra-badge:not(:defined)[size=lg], astra-avatar:not(:defined)[size=lg], astra-switch:not(:defined)[size=lg], astra-checkbox:not(:defined)[size=lg], astra-radio:not(:defined)[size=lg], astra-loading:not(:defined)[size=lg], astra-notification-bell:not(:defined)[size=lg], astra-theme-toggle:not(:defined)[size=lg], astra-workspace-switcher:not(:defined)[size=lg], astra-progress-ring:not(:defined)[size=lg], astra-dropdown:not(:defined)[size=lg], astra-user-menu:not(:defined)[size=lg],
astra-input:not(:defined)[size=lg], astra-textarea:not(:defined)[size=lg], astra-select:not(:defined)[size=lg], astra-combobox:not(:defined)[size=lg], astra-number-input:not(:defined)[size=lg], astra-date-picker:not(:defined)[size=lg], astra-date-range-picker:not(:defined)[size=lg], astra-time-picker:not(:defined)[size=lg], astra-otp-input:not(:defined)[size=lg], astra-tag-input:not(:defined)[size=lg], astra-slider:not(:defined)[size=lg], astra-color-picker:not(:defined)[size=lg], astra-file-upload:not(:defined)[size=lg], astra-media-picker:not(:defined)[size=lg], astra-content-picker:not(:defined)[size=lg], astra-progress-bar:not(:defined)[size=lg] {
  min-height: 3.25rem;
}

astra-input:not(:defined)[label], astra-textarea:not(:defined)[label], astra-select:not(:defined)[label], astra-combobox:not(:defined)[label], astra-number-input:not(:defined)[label], astra-date-picker:not(:defined)[label], astra-date-range-picker:not(:defined)[label], astra-time-picker:not(:defined)[label], astra-otp-input:not(:defined)[label], astra-tag-input:not(:defined)[label], astra-slider:not(:defined)[label], astra-color-picker:not(:defined)[label], astra-file-upload:not(:defined)[label], astra-media-picker:not(:defined)[label], astra-content-picker:not(:defined)[label], astra-progress-bar:not(:defined)[label] {
  min-height: calc(4rem + var(--space-1));
}

/* Round things stay round. */
astra-badge:not(:defined),
astra-avatar:not(:defined),
astra-switch:not(:defined),
astra-progress-ring:not(:defined),
astra-loading:not(:defined) {
  border-radius: var(--radius-pill);
}

astra-badge:not(:defined) {
  min-height: 1.75rem;
  min-width: 1.75rem;
}

astra-avatar:not(:defined),
astra-progress-ring:not(:defined),
astra-loading:not(:defined),
astra-notification-bell:not(:defined),
astra-theme-toggle:not(:defined) {
  min-height: 2.25rem;
  min-width: 2.25rem;
}

/* Checkbox and radio are a control the size of a glyph followed by a label the
   page needs to read. The plate is the control; the label keeps its ink. */
astra-checkbox:not(:defined),
astra-radio:not(:defined) {
  background: none;
  color: inherit;
  min-height: 1.5rem;
  min-width: 0;
}

/* An icon is a glyph-sized hole in a line of text. It paints nothing — a plate
   here would put grey chips through every notice and menu label — but it holds
   its box, off the SAME --icon-size-* tokens astra-icon's own :host reads, so
   there is one set of numbers rather than an approximation of one.
   THIS IS THE EARLIEST-SETTLING RESERVATION ON THE PAGE and it earns its keep:
   astra-icon is imported inline in every template's <head> (to hand it the
   sprite URL) so it upgrades on its own, ~30ms after first paint, hundreds of
   times before components.js finishes. Measured on portal-shop-product-edit,
   guessing 1.25em here instead of the token moved a whole card column 450px at
   3,449ms — 0.140 of layout shift from one wrong length. */
astra-icon:not(:defined) {
  display: inline-block;
  line-height: 0;
  vertical-align: middle;
  inline-size: var(--icon-size-md);
  block-size: var(--icon-size-md);
}

astra-icon:not(:defined)[size=xs] {
  inline-size: var(--icon-size-xs);
  block-size: var(--icon-size-xs);
}

astra-icon:not(:defined)[size=sm] {
  inline-size: var(--icon-size-sm);
  block-size: var(--icon-size-sm);
}

astra-icon:not(:defined)[size=lg] {
  inline-size: var(--icon-size-lg);
  block-size: var(--icon-size-lg);
}

astra-icon:not(:defined)[size=xl] {
  inline-size: var(--icon-size-xl);
  block-size: var(--icon-size-xl);
}

/* A table's rows arrive from script on most pages, so its light DOM is empty and
   its height pre-upgrade is zero while its height after is hundreds of pixels.
   16rem is roughly a header plus five rows — enough that the page below it does
   not travel, not so much that a three-row table leaves a hole. */
astra-table:not(:defined),
astra-chart:not(:defined),
astra-kanban:not(:defined),
astra-chat:not(:defined),
astra-calendar:not(:defined),
astra-batch-review:not(:defined),
astra-media-picker:not(:defined),
astra-content-picker:not(:defined),
astra-rich-text:not(:defined),
astra-file-upload:not(:defined) {
  min-height: 16rem;
  border-radius: var(--radius-card);
}

/* Server-rendered rows are the exception: those pages put the real data in the
   light DOM, so there is nothing to reserve and everything to show. */
astra-table:not(:defined):has(astra-table-row) {
  min-height: 0;
  background: none;
  color: inherit;
}

astra-empty-state:not(:defined) {
  min-height: 12rem;
  border-radius: var(--radius-card);
}

astra-pagination:not(:defined),
astra-stats-card:not(:defined),
astra-progress-bar:not(:defined),
astra-notification-item:not(:defined),
astra-batch-progress:not(:defined) {
  min-height: 3rem;
}

astra-audio:not(:defined),
astra-audio-trimmer:not(:defined),
astra-video:not(:defined) {
  min-height: 6rem;
  border-radius: var(--radius-card);
}

astra-card:not(:defined), astra-accordion:not(:defined), astra-tabs:not(:defined), astra-tab-panel:not(:defined), astra-timeline:not(:defined), astra-stepper:not(:defined), astra-breadcrumbs:not(:defined), astra-radio-group:not(:defined), astra-table-row:not(:defined) {
  display: block;
}

/* The one shape worth painting early. A card is the estate's commonest container
   and an unpainted one is a paragraph floating on the page background; giving it
   its own surface is the difference between "the page is loading" and "the page
   is broken". Matched to astra-card's own resting treatment, not invented. */
/* --space-inset, NOT --space-inset-base. The ladder's default rung has no suffix
   (xs / sm / <none> / lg / xl in tokens/_spacing.scss), and the first draft here
   wrote `--space-inset-base`, which does not exist: the declaration was invalid at
   computed-value time and every held card had ZERO padding. It still looked
   plausible in a screenshot, which is exactly why it is worth writing down.
   The values track astra-card's own `.card__body` rungs, and matching them is not
   cosmetic: the checkout pages mount Stripe Elements inside a card, and Stripe
   measures the box it is given. A card whose inner width changes when it upgrades
   would resize the field under a mounted iframe (docs/SPACING-WORKLIST.md §6.1). */
astra-card:not(:defined) {
  box-sizing: border-box;
  background: var(--surface-raised);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-card);
  padding: var(--space-inset);
}

astra-card:not(:defined)[padding=none],
astra-card:not(:defined)[variant=flush] {
  padding: 0;
}

astra-card:not(:defined)[padding=sm] {
  padding: var(--space-inset-sm);
}

astra-card:not(:defined)[padding=lg] {
  padding: var(--space-inset-xl);
}

/* A tabbed page renders EVERY panel into the document; the upgrade then collapses
   it to one. On royalties/reports that is four panels' worth of page that vanishes
   — the single largest layout shift in the estate. Showing only the first panel
   pre-upgrade is not always the right panel (a page can open on another), but it
   is always the right AMOUNT of page, and the correct one arrives a moment later. */
astra-tab-panel:not(:defined) ~ astra-tab-panel:not(:defined) {
  min-height: 0;
  max-height: 0;
  overflow: hidden;
  content-visibility: hidden;
  contain-intrinsic-size: 0;
  animation: astra-pre-upgrade-restore 0s var(--astra-pre-upgrade-chrome-reveal) forwards;
}

/* Slotted card furniture reads in source order pre-upgrade, which is header,
   body, footer — already the right order. Nothing to do but keep it block. */
astra-card:not(:defined) > [slot] {
  display: block;
}

/* THE CHROME IS NOT WHERE IT LOOKS LIKE IT IS. Everything carrying a `slot`
   attribute is destined for the topbar or the rail; in the document it sits
   ahead of the page as a run of inline text and a 32px logo SVG. It is also
   INERT — an <astra-nav-item> is not an <a>, so revealing it early offers an
   operator navigation that cannot navigate. Held until the shell can place it,
   then restored by the failsafe so a page whose script never arrives still
   shows what its chrome said. Held to zero height rather than to `display: none`
   for exactly that reason — see the restore keyframe. */
astra-shell-admin:not(:defined) > [slot], astra-shell-ninefive:not(:defined) > [slot], astra-shell-partner:not(:defined) > [slot], astra-shell-identity:not(:defined) > [slot], astra-shell-invoice:not(:defined) > [slot], astra-shell-auth:not(:defined) > [slot] {
  /* !important, for the same reason base/_base.scss uses it on [hidden]: this
     rule has to beat markup it does not own. NineFive's topbar brand is written
     `<span slot="logo" style="display:inline-flex; …">`, and an inline style beats
     any author rule without it — so the span stayed inline-level, and although its
     own height was 0 the LINE BOX it sat on was not: every ninefive page started
     23px lower than it finished. Only `display` needs the escape; everything below
     is uncontested. */
  display: block !important;
  /* min-height: 0 IS LOAD-BEARING, not tidiness. The used height of a box is
     max(min-height, min(max-height, height)) — MIN WINS OVER MAX — so a slotted
     <astra-input> carrying the 2.75rem control reservation from section 3 stayed
     44px tall through `max-height: 0` and the four topbar controls stacked up
     into 168px of grey plates above the page. Measured, not reasoned: the shell
     children read 44/44/36/44px with this line missing. */
  min-height: 0;
  min-width: 0;
  max-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  overflow: hidden;
  content-visibility: hidden;
  contain-intrinsic-size: 0;
  animation: astra-pre-upgrade-restore 0s var(--astra-pre-upgrade-chrome-reveal) forwards;
}
