/* ============================================================================================
   ScaleLounge design system
   ============================================================================================

   One place for the brand. Every surface (public site, client portal, admin, score, emails where
   CSS survives) consumes these tokens instead of carrying its own hex values, which is what the
   codebase did before: scalelounge.html held 140 hard-coded colours, portal.html 209, admin.html
   194, and each page redefined its own :root.

   THE PALETTE IS NOT A GUESS. It was read out of the approved mockup PDF by inflating its content
   streams and totalling the painted area per colour. That is where the extended neutral ramps come
   from, and it is why champagne appears here as a small-area accent: in the approved design it
   covers about 3% of what the ivory does.

   CONTRAST IS MEASURED, NOT ASSUMED. Every pair below that carries text was checked against WCAG.
   Two results shaped the system and must not be undone:

     champagne (#B79A63) on ivory (#F6F3ED) is 2.43:1. It FAILS at every size. Champagne is
     therefore never text on a light surface. On charcoal it is 6.68:1 and fine.

     stone (#D8D3C8) on ivory is 1.35:1, far under the 3:1 a UI component needs. Stone is a
     quiet divider, never a focus ring and never the only signal that something is selected.

   Ratios are recorded next to each token so the next person can see the cost of changing one.
   ============================================================================================ */

/* ---- 1. Brand primitives -------------------------------------------------------------------
   The five approved colours, plus the ramps the mockup actually painted around them. Nothing in
   the application should reference these directly; use the semantic tokens in section 3. */
:root {
  --sl-ivory: #F6F3ED;                 /* Warm Ivory   - the page */
  --sl-charcoal: #15171A;              /* Deep Charcoal - type and dark sections */
  --sl-champagne: #B79A63;             /* Muted Champagne - accent only */
  --sl-forest: #24332B;                /* Deep Forest  - action and confidence */
  --sl-stone: #D8D3C8;                 /* Soft Stone   - borders */

  /* Light surfaces, lightest first. Taken from the mockup's own fills. */
  --sl-ivory-0: #FBFAF7;               /* raised card, near white but still warm */
  --sl-ivory-1: #F8F6F0;
  --sl-ivory-2: #F6F3ED;               /* = Warm Ivory, the page base */
  --sl-ivory-3: #F0ECE3;
  --sl-ivory-4: #EFEAE0;               /* alternating band */
  --sl-ivory-5: #ECE8E0;               /* pressed / hovered light surface */

  /* Stone ramp: dividers and borders, subtle to strong. */
  --sl-stone-1: #E7E2D9;
  --sl-stone-2: #DEDAD1;
  --sl-stone-3: #D8D3C8;               /* = Soft Stone */

  /* Charcoal ramp: dark sections and the surfaces that sit on them. */
  --sl-charcoal-0: #15171A;            /* = Deep Charcoal, the dark page */
  --sl-charcoal-1: #1C1F1E;            /* raised surface on dark */
  --sl-charcoal-2: #1E2221;            /* raised further */
  --sl-charcoal-3: #373B39;            /* borders on dark */

  /* Forest: action. Hover goes lighter so the button lifts rather than sinks into the page. */
  --sl-forest-0: #24332B;
  --sl-forest-hover: #2E4136;
  --sl-forest-active: #1B2721;
  --sl-forest-tint: #E8EDE8;           /* selected row, quiet success surface */

  /* Champagne. `ink` is the only champagne-family colour allowed as text on a light surface
     (4.93:1). The base tone is for rules, marks, borders and dark-background text. */
  --sl-champagne-0: #B79A63;
  --sl-champagne-ink: #7E663A;         /* 4.93:1 on ivory - AA */
  --sl-champagne-soft: rgba(183, 154, 99, .14);
}

/* ---- 2. Type, space, radius, elevation, motion ---------------------------------------------
   Inter for everything, Inter Display for large marketing headlines.

   Both faces come out of ONE file. Inter v4 carries an optical-size axis (opsz 14 to 32), and
   "Inter Display" is simply that axis at its top end: tighter spacing and slightly closed apertures
   for large type. So the second @font-face below re-declares the same woff2 with opsz pinned to 32.
   The browser downloads 352KB once and gets both, which is why there is no separate display file to
   keep in sync.

   Self-hosted deliberately. The site made a documented choice not to pull fonts from a third party,
   and Inter is SIL OFL, redistributed here with its licence in assets/fonts/Inter-LICENSE.txt. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/inter-variable.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter Display';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/inter-variable.woff2') format('woff2');
  font-variation-settings: 'opsz' 32;
}

/* Titles run on DM Sans, because Katie asked for them to match the ScaleLounge wordmark.
   That was settled by measurement rather than taste: the logo's wordmark is 837px wide over a
   101px cap height, a ratio of 8.287. Rendered at the same cap height, DM Sans at 500 comes out at
   8.280, the closest of fourteen candidates. Manrope was next at 8.251. Montserrat and Work Sans
   were the furthest away, at 9.37 and 9.26, which is why the titles never looked related to the
   logo before. Latin subset, 37KB, SIL OFL, licence alongside it in assets/fonts/. */
@font-face {
  font-family: 'DM Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/fonts/dmsans-variable.woff2') format('woff2');
}

:root {
  --sl-font: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  /* DM Sans for titles (it matches the wordmark), Inter behind it for anything DM Sans's latin
     subset does not carry, then the system stack. */
  --sl-font-display: 'DM Sans', 'Inter Display', 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* Display sizes track the mockup's own ratios. clamp() so a headline never has to be crammed. */
  --sl-t-hero: clamp(2.6rem, 1.4rem + 3.6vw, 4.6rem);
  --sl-t-h1: clamp(2.1rem, 1.3rem + 2.6vw, 3.4rem);
  --sl-t-h2: clamp(1.7rem, 1.2rem + 1.7vw, 2.5rem);
  --sl-t-h3: clamp(1.25rem, 1.05rem + .7vw, 1.6rem);
  --sl-t-lead: clamp(1.02rem, .96rem + .3vw, 1.18rem);
  --sl-t-body: 1.0625rem;   /* 17px. Reading size, not the minimum a browser will render.   */
  --sl-t-sm: 1rem;         /* 16px. Labels, table bodies, small buttons: still full copy.  */
  --sl-t-xs: .875rem;      /* 14px. The floor for anything a person is meant to read.      */
  --sl-t-eyebrow: .8125rem;/* 13px, and only ever set in caps with wide tracking.          */

  /* Named roles. A screen should say what a piece of text IS, not pick a number: that is how
     a codebase ends up with eleven sizes between 11 and 15px and no rule about any of them.
     These follow the client/product scale, so the portals and the admin share one vocabulary. */
  --sl-t-page: clamp(1.75rem, 1.35rem + 1.1vw, 2.25rem);   /* 28 to 36px  PageTitle       */
  --sl-t-page-sub: 1.125rem;                               /* 18px        PageSubtitle    */
  --sl-t-dash: clamp(1.55rem, 1.25rem + .9vw, 2rem);       /* 25 to 32px  DashboardTitle  */
  --sl-t-section: 1.375rem;                                /* 22px        SectionTitle    */
  --sl-t-section-desc: 1.0625rem;                          /* 17px        SectionDesc     */
  --sl-t-card: 1.125rem;                                   /* 18px        CardTitle       */
  --sl-t-card-desc: 1rem;                                  /* 16px        CardDesc        */
  --sl-t-metric: clamp(2rem, 1.55rem + 1.4vw, 2.75rem);    /* 32 to 44px  MetricValue     */
  --sl-t-metric-label: .9375rem;                           /* 15px        MetricLabel     */
  --sl-t-nav: 1rem;                                        /* 16px        Navigation      */
  --sl-t-btn: 1rem;                                        /* 16px        ButtonText      */
  --sl-t-table: .9375rem;                                  /* 15px        Table body      */
  --sl-t-meta: .875rem;                                    /* 14px        Metadata ONLY   */

  /* Medium for display, per the brief: not thin, not overly bold. */
  --sl-w-display: 500;
  --sl-w-body: 400;
  --sl-w-medium: 500;
  --sl-w-semi: 600;

  --sl-lh-display: 1.08;
  --sl-lh-heading: 1.2;
  --sl-lh-body: 1.6;
  --sl-tracking-display: -.022em;
  --sl-tracking-eyebrow: .13em;

  --sl-space-1: 4px;  --sl-space-2: 8px;   --sl-space-3: 12px; --sl-space-4: 16px;
  --sl-space-5: 24px; --sl-space-6: 32px;  --sl-space-7: 48px; --sl-space-8: 64px;
  --sl-space-9: 96px; --sl-space-10: 128px;

  --sl-radius-sm: 6px;
  --sl-radius: 10px;
  --sl-radius-lg: 14px;
  --sl-radius-xl: 20px;
  --sl-radius-pill: 999px;

  /* Minimal shadows on purpose. Premium here comes from spacing, not from depth effects. */
  --sl-shadow-sm: 0 1px 2px rgba(21, 23, 26, .05);
  --sl-shadow: 0 2px 8px rgba(21, 23, 26, .06);
  --sl-shadow-lg: 0 18px 44px -26px rgba(21, 23, 26, .28);

  --sl-ease: cubic-bezier(.22, .9, .3, 1);
  --sl-dur: .2s;
  --sl-dur-slow: .34s;

  --sl-measure: 68ch;                  /* readable line length for body copy */
  --sl-container: 1120px;
}

/* ---- 3. Semantic tokens ---------------------------------------------------------------------
   What the application actually uses. Light context is the default because the public site and the
   portal are predominantly ivory. Anything inside .sl-dark flips to the charcoal set. */
:root {
  --background-primary: var(--sl-ivory-2);
  --background-secondary: var(--sl-ivory-4);
  --surface-primary: var(--sl-ivory-0);
  --surface-elevated: #FFFFFF;
  --surface-sunken: var(--sl-ivory-3);
  --surface-dark: var(--sl-charcoal-0);

  --text-primary: var(--sl-charcoal-0);      /* 16.22:1 on ivory - AAA */
  --text-secondary: #5C625E;                 /*  5.64:1 on ivory - AA  */
  --text-tertiary: #6B716D;                  /*  4.51:1 on ivory - AA  */
  --text-on-dark: var(--sl-ivory-2);         /* 16.22:1 on charcoal - AAA */
  --text-on-dark-secondary: #A9AEAB;         /*  7.98:1 on charcoal - AAA */
  --text-on-dark-tertiary: #8C938F;          /*  5.72:1 on charcoal - AA  */
  --text-accent: var(--sl-champagne-ink);    /*  4.93:1 on ivory - AA. NOT --sl-champagne. */

  --border-subtle: var(--sl-stone-1);
  --border-strong: var(--sl-stone-3);
  --border-dark: var(--sl-charcoal-3);

  --action-primary: var(--sl-forest-0);
  --action-primary-hover: var(--sl-forest-hover);
  --action-primary-active: var(--sl-forest-active);
  --action-primary-text: var(--sl-ivory-2);  /* 11.98:1 on forest - AAA */
  --action-secondary: var(--sl-charcoal-0);
  --action-secondary-text: var(--sl-ivory-2);

  --accent: var(--sl-champagne-0);
  --accent-soft: var(--sl-champagne-soft);

  /* Forest, because it is the only brand colour that clears 3:1 against ivory (11.98:1).
     Stone and champagne both fail as a focus indicator. */
  --focus-ring: var(--sl-forest-0);
  --focus-ring-dark: var(--sl-champagne-0);

  /* Semantic status stays a separate system. These are functional, not decorative brand colours,
     and they are tuned for contrast on ivory rather than picked for looks. */
  --status-success: #2F6B4F;
  --status-success-surface: #E8EDE8;
  --status-warning: #8A6318;
  --status-warning-surface: #F6EEDD;
  --status-error: #A33A34;
  --status-error-surface: #F7E9E7;
  --status-info: #2C5468;
  --status-info-surface: #E7EFF3;
}

/* Dark context. Applied to a section, a card or the whole page. */
.sl-dark {
  --background-primary: var(--sl-charcoal-0);
  --background-secondary: var(--sl-charcoal-1);
  --surface-primary: var(--sl-charcoal-1);
  --surface-elevated: var(--sl-charcoal-2);
  --surface-sunken: #101214;
  --text-primary: var(--sl-ivory-2);
  --text-secondary: var(--text-on-dark-secondary);
  --text-tertiary: var(--text-on-dark-tertiary);
  --text-accent: var(--sl-champagne-0);      /* 6.68:1 on charcoal - fine here, unlike on ivory */
  --border-subtle: var(--sl-charcoal-3);
  --border-strong: #4A4F4C;
  --focus-ring: var(--sl-champagne-0);
  background: var(--background-primary);
  color: var(--text-primary);
}

/* ---- 4. Base ---------------------------------------------------------------------------------
   Loading brand.css is what makes a page a ScaleLounge page, so it sets the family on `body`
   itself rather than waiting for a class. That matters because fonts.css still serves Plus Jakarta
   Sans on purpose: index.html is katielendel.com, Katie's personal site, and it shares that file.
   Rebranding fonts.css would have silently changed the personal site too. On any page that loads
   both, brand.css must come AFTER fonts.css so Inter wins. */
body {
  font-family: var(--sl-font);
  font-optical-sizing: auto;
}
h1, h2, h3, h4, h5, h6 {
  font-family: var(--sl-font-display);
  font-weight: var(--sl-w-display);
  letter-spacing: var(--sl-tracking-display);
}

.sl-body,
body.sl-body {
  font-family: var(--sl-font);
  font-weight: var(--sl-w-body);
  font-size: var(--sl-t-body);
  line-height: var(--sl-lh-body);
  color: var(--text-primary);
  background: var(--background-primary);
  font-optical-sizing: auto;           /* let opsz track the size for everything but the display face */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

.sl-display, .sl-h1, .sl-h2, .sl-h3 {
  font-family: var(--sl-font-display);
  font-weight: var(--sl-w-display);
  line-height: var(--sl-lh-heading);
  letter-spacing: var(--sl-tracking-display);
  color: var(--text-primary);
  margin: 0;
  text-wrap: balance;
}
.sl-display { font-size: var(--sl-t-hero); line-height: var(--sl-lh-display); }
.sl-h1 { font-size: var(--sl-t-h1); }
.sl-h2 { font-size: var(--sl-t-h2); }
.sl-h3 { font-size: var(--sl-t-h3); font-weight: var(--sl-w-semi); letter-spacing: -.012em; }

.sl-lead { font-size: var(--sl-t-lead); color: var(--text-secondary); max-width: var(--sl-measure); margin: 0; }
.sl-muted { color: var(--text-secondary); }
.sl-dim { color: var(--text-tertiary); }

/* The eyebrow is where champagne earns its keep on dark. On light it uses the ink tone, because
   the base champagne is 2.43:1 there and would be a compliance failure in small caps type. */
.sl-eyebrow {
  font-size: var(--sl-t-eyebrow);
  font-weight: var(--sl-w-semi);
  letter-spacing: var(--sl-tracking-eyebrow);
  text-transform: uppercase;
  color: var(--text-accent);
  margin: 0 0 var(--sl-space-3);
}

.sl-container { width: 100%; max-width: var(--sl-container); margin-inline: auto; padding-inline: var(--sl-space-5); }
.sl-section { padding-block: clamp(56px, 7vw, 112px); }
.sl-rule { height: 1px; border: 0; background: var(--border-subtle); margin: 0; }
.sl-rule-accent { height: 2px; width: 44px; border: 0; background: var(--accent); margin: 0; }

/* ---- 5. Focus -------------------------------------------------------------------------------
   One visible focus treatment everywhere. :focus-visible so a mouse click does not draw it but a
   keyboard tab always does. */
.sl-body :focus-visible,
.sl-btn:focus-visible,
.sl-input:focus-visible,
.sl-select:focus-visible,
.sl-textarea:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
  border-radius: var(--sl-radius-sm);
}

/* ---- 6. Buttons -----------------------------------------------------------------------------
   One primary action per visual area, in forest. Champagne is deliberately not a button colour:
   it is an accent, and charcoal-on-champagne is only 6.68:1 where forest gives 11.98:1. */
.sl-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sl-space-2);
  font-family: var(--sl-font); font-size: var(--sl-t-btn); font-weight: var(--sl-w-semi);
  line-height: 1; letter-spacing: -.005em;
  padding: 13px 22px; border-radius: var(--sl-radius); border: 1px solid transparent;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background-color var(--sl-dur) var(--sl-ease), border-color var(--sl-dur) var(--sl-ease), color var(--sl-dur) var(--sl-ease);
}
.sl-btn-primary { background: var(--action-primary); color: var(--action-primary-text); }
.sl-btn-primary:hover { background: var(--action-primary-hover); }
.sl-btn-primary:active { background: var(--action-primary-active); }

.sl-btn-secondary { background: transparent; color: var(--text-primary); border-color: var(--border-strong); }
.sl-btn-secondary:hover { border-color: var(--action-primary); background: var(--sl-ivory-5); }
.sl-dark .sl-btn-secondary { color: var(--text-primary); border-color: var(--border-strong); }
.sl-dark .sl-btn-secondary:hover { background: rgba(246, 243, 237, .08); border-color: var(--accent); }

.sl-btn-solid-dark { background: var(--action-secondary); color: var(--action-secondary-text); }
.sl-btn-solid-dark:hover { background: #22262A; }

.sl-btn-tertiary {
  background: none; border: 0; padding: 4px 2px; color: var(--text-primary);
  text-decoration: underline; text-underline-offset: 4px;
  text-decoration-color: var(--border-strong); text-decoration-thickness: 1px;
}
.sl-btn-tertiary:hover { text-decoration-color: var(--action-primary); }

.sl-btn-sm { padding: 10px 17px; font-size: var(--sl-t-btn); }
.sl-btn-lg { padding: 17px 32px; font-size: 1.125rem; }
.sl-btn[disabled], .sl-btn[aria-disabled="true"] { opacity: .45; cursor: not-allowed; pointer-events: none; }
.sl-btn-block { width: 100%; }

/* ---- 7. Cards -------------------------------------------------------------------------------
   Restrained on purpose. The brief is explicit that premium does not mean more boxes, so a card
   is a light surface with a stone hairline and almost no shadow. */
.sl-card {
  background: var(--surface-primary);
  border: 1px solid var(--border-subtle);
  border-radius: var(--sl-radius-lg);
  padding: var(--sl-space-5);
  box-shadow: var(--sl-shadow-sm);
}
.sl-card-flat { box-shadow: none; }
.sl-card-dark { background: var(--sl-charcoal-1); border-color: var(--sl-charcoal-3); color: var(--text-on-dark); }
.sl-card-selected { border-color: var(--action-primary); box-shadow: inset 0 0 0 1px var(--action-primary); }
/* Selection is carried by the border AND the left rule, never by colour alone. */
.sl-card-featured { border-color: var(--border-strong); border-left: 3px solid var(--accent); }

/* ---- 8. Forms -------------------------------------------------------------------------------- */
.sl-field { display: block; margin-bottom: var(--sl-space-4); }
.sl-label { display: block; font-size: var(--sl-t-sm); font-weight: var(--sl-w-medium); color: var(--text-primary); margin-bottom: var(--sl-space-2); }
.sl-hint { display: block; font-size: var(--sl-t-xs); color: var(--text-secondary); margin-top: var(--sl-space-2); }

.sl-input, .sl-textarea, .sl-select {
  width: 100%; font-family: var(--sl-font); font-size: var(--sl-t-body); color: var(--text-primary);
  background: var(--surface-elevated);
  border: 1px solid var(--border-strong); border-radius: var(--sl-radius);
  padding: 12px 14px;
  transition: border-color var(--sl-dur) var(--sl-ease), box-shadow var(--sl-dur) var(--sl-ease);
}
.sl-input::placeholder, .sl-textarea::placeholder { color: var(--text-tertiary); }
.sl-input:hover, .sl-textarea:hover, .sl-select:hover { border-color: var(--text-tertiary); }
.sl-input:focus, .sl-textarea:focus, .sl-select:focus {
  border-color: var(--action-primary); box-shadow: 0 0 0 3px rgba(36, 51, 43, .12); outline: none;
}
.sl-textarea { min-height: 120px; resize: vertical; line-height: var(--sl-lh-body); }
.sl-input[disabled], .sl-textarea[disabled], .sl-select[disabled] { background: var(--sl-ivory-5); color: var(--text-tertiary); cursor: not-allowed; }

/* Validation never relies on colour alone: the message text carries the meaning. */
.sl-input[aria-invalid="true"], .sl-textarea[aria-invalid="true"] { border-color: var(--status-error); }
.sl-error { display: block; font-size: var(--sl-t-xs); color: var(--status-error); margin-top: var(--sl-space-2); font-weight: var(--sl-w-medium); }
.sl-ok { display: block; font-size: var(--sl-t-xs); color: var(--status-success); margin-top: var(--sl-space-2); font-weight: var(--sl-w-medium); }

.sl-check { display: inline-flex; align-items: flex-start; gap: var(--sl-space-3); cursor: pointer; font-size: var(--sl-t-sm); }
.sl-check input { width: 18px; height: 18px; accent-color: var(--action-primary); margin: 1px 0 0; flex: 0 0 auto; }

/* ---- 9. Badges and status -------------------------------------------------------------------- */
.sl-badge {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--sl-t-xs); font-weight: var(--sl-w-semi); letter-spacing: .02em;
  padding: 4px 10px; border-radius: var(--sl-radius-pill);
  background: var(--sl-ivory-5); color: var(--text-secondary); border: 1px solid var(--border-subtle);
}
.sl-badge-accent { background: var(--accent-soft); color: var(--text-accent); border-color: rgba(183, 154, 99, .34); }
.sl-badge-forest { background: var(--sl-forest-tint); color: var(--sl-forest-0); border-color: rgba(36, 51, 43, .22); }
.sl-badge-success { background: var(--status-success-surface); color: var(--status-success); border-color: rgba(47, 107, 79, .25); }
.sl-badge-warning { background: var(--status-warning-surface); color: var(--status-warning); border-color: rgba(138, 99, 24, .25); }
.sl-badge-error { background: var(--status-error-surface); color: var(--status-error); border-color: rgba(163, 58, 52, .25); }

/* ---- 10. Tables ------------------------------------------------------------------------------ */
.sl-table { width: 100%; border-collapse: collapse; font-size: var(--sl-t-table); }
.sl-table th {
  text-align: left; font-weight: var(--sl-w-semi); font-size: var(--sl-t-xs);
  letter-spacing: .06em; text-transform: uppercase; color: var(--text-tertiary);
  padding: 10px 14px; border-bottom: 1px solid var(--border-strong); white-space: nowrap;
}
.sl-table td { padding: 14px; border-bottom: 1px solid var(--border-subtle); color: var(--text-primary); vertical-align: top; }
.sl-table tbody tr:hover { background: var(--sl-ivory-1); }
.sl-table tbody tr[aria-selected="true"] { background: var(--sl-forest-tint); box-shadow: inset 3px 0 0 var(--action-primary); }
.sl-table-wrap { overflow-x: auto; border: 1px solid var(--border-subtle); border-radius: var(--sl-radius-lg); background: var(--surface-primary); }

/* ---- 11. Modals, drawers, toasts, tooltips --------------------------------------------------- */
.sl-scrim { position: fixed; inset: 0; background: rgba(21, 23, 26, .48); z-index: 200; }
.sl-modal {
  position: fixed; z-index: 201; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 64px); overflow: auto;
  background: var(--surface-elevated); border: 1px solid var(--border-subtle);
  border-radius: var(--sl-radius-xl); box-shadow: var(--sl-shadow-lg); padding: var(--sl-space-6);
}
.sl-drawer {
  position: fixed; z-index: 201; top: 0; right: 0; height: 100vh; width: min(460px, 100vw);
  background: var(--surface-elevated); border-left: 1px solid var(--border-subtle);
  box-shadow: var(--sl-shadow-lg); padding: var(--sl-space-6); overflow: auto;
}
.sl-toast {
  display: flex; align-items: center; gap: var(--sl-space-3);
  background: var(--sl-charcoal-0); color: var(--sl-ivory-2);
  border-radius: var(--sl-radius); padding: 13px 18px; font-size: var(--sl-t-sm);
  box-shadow: var(--sl-shadow-lg);
}
.sl-tooltip {
  background: var(--sl-charcoal-0); color: var(--sl-ivory-2);
  font-size: var(--sl-t-xs); padding: 7px 10px; border-radius: var(--sl-radius-sm);
  box-shadow: var(--sl-shadow); max-width: 260px; line-height: 1.45;
}

/* ---- 12. Loading and empty states ------------------------------------------------------------
   A skeleton, not a spinner with brand colours in it. Sweep is suppressed under reduced motion. */
.sl-skeleton {
  background: linear-gradient(90deg, var(--sl-ivory-3) 25%, var(--sl-ivory-5) 37%, var(--sl-ivory-3) 63%);
  background-size: 400% 100%;
  animation: sl-sweep 1.4s ease-in-out infinite;
  border-radius: var(--sl-radius-sm);
}
@keyframes sl-sweep { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
.sl-skeleton-line { height: 12px; margin-bottom: 10px; }
.sl-skeleton-line:last-child { width: 62%; }

.sl-empty { text-align: center; padding: var(--sl-space-8) var(--sl-space-5); max-width: 46ch; margin-inline: auto; }
.sl-empty-mark { color: var(--accent); margin-bottom: var(--sl-space-4); }
.sl-empty h3 { font-family: var(--sl-font-display); font-weight: var(--sl-w-medium); font-size: var(--sl-t-h3); color: var(--text-primary); margin: 0 0 var(--sl-space-2); }
.sl-empty p { color: var(--text-secondary); margin: 0 0 var(--sl-space-5); }

/* ---- 13. Navigation -------------------------------------------------------------------------- */
.sl-nav-link {
  font-size: var(--sl-t-sm); font-weight: var(--sl-w-medium); color: var(--text-secondary);
  text-decoration: none; padding: 8px 2px; transition: color var(--sl-dur) var(--sl-ease);
}
.sl-nav-link:hover { color: var(--text-primary); }
/* Current page is marked by weight and a rule, not by colour alone. */
.sl-nav-link[aria-current] { color: var(--text-primary); font-weight: var(--sl-w-semi); box-shadow: inset 0 -2px 0 var(--accent); }

.sl-side-link {
  display: flex; align-items: center; gap: var(--sl-space-3);
  padding: 10px 14px; border-radius: var(--sl-radius); font-size: var(--sl-t-sm);
  color: var(--text-secondary); text-decoration: none;
  transition: background-color var(--sl-dur) var(--sl-ease), color var(--sl-dur) var(--sl-ease);
}
.sl-side-link:hover { background: var(--sl-ivory-5); color: var(--text-primary); }
.sl-side-link[aria-current] { background: var(--sl-forest-tint); color: var(--sl-forest-0); font-weight: var(--sl-w-semi); box-shadow: inset 3px 0 0 var(--action-primary); }

/* ---- 14. Motion ------------------------------------------------------------------------------
   Calm only: fades and small rises. Nothing pulses, glows or floats. */
.sl-rise { animation: sl-rise var(--sl-dur-slow) var(--sl-ease) both; }
@keyframes sl-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.sl-fade { animation: sl-fade var(--sl-dur-slow) var(--sl-ease) both; }
@keyframes sl-fade { from { opacity: 0; } to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .sl-rise, .sl-fade, .sl-skeleton { animation: none !important; }
  .sl-skeleton { background: var(--sl-ivory-3); }
  * { transition-duration: .01ms !important; }
}


/* ---------------------------------------------------------------- text roles
   One vocabulary for every ScaleLounge surface. Public pages are more editorial and set their own
   display sizes; these are the product scale, shared by the client portal and the admin. */
.sl-page-title    { font-family: var(--sl-font-display); font-size: var(--sl-t-page); font-weight: var(--sl-w-display);
                    line-height: 1.12; letter-spacing: -.022em; color: var(--text-primary); margin: 0; }
.sl-page-sub      { font-size: var(--sl-t-page-sub); line-height: 1.5; color: var(--text-secondary);
                    max-width: var(--sl-measure); margin: var(--sl-space-2) 0 0; }
.sl-dash-title    { font-family: var(--sl-font-display); font-size: var(--sl-t-dash); font-weight: var(--sl-w-display);
                    line-height: 1.15; letter-spacing: -.02em; color: var(--text-primary); margin: 0; }
.sl-section-title { font-family: var(--sl-font-display); font-size: var(--sl-t-section); font-weight: var(--sl-w-semi);
                    line-height: 1.25; letter-spacing: -.015em; color: var(--text-primary); margin: 0; }
.sl-section-desc  { font-size: var(--sl-t-section-desc); line-height: 1.55; color: var(--text-secondary);
                    max-width: var(--sl-measure); margin: var(--sl-space-2) 0 0; }
.sl-card-title    { font-size: var(--sl-t-card); font-weight: var(--sl-w-semi); line-height: 1.3;
                    letter-spacing: -.01em; color: var(--text-primary); margin: 0; }
.sl-card-desc     { font-size: var(--sl-t-card-desc); line-height: 1.5; color: var(--text-secondary); margin: 0; }
.sl-body          { font-size: var(--sl-t-body); line-height: var(--sl-lh-body, 1.6); color: var(--text-primary); }
.sl-body-muted    { font-size: var(--sl-t-body); line-height: var(--sl-lh-body, 1.6); color: var(--text-secondary); }
.sl-meta          { font-size: var(--sl-t-meta); line-height: 1.45; color: var(--text-tertiary); }
.sl-metric        { font-family: var(--sl-font-display); font-size: var(--sl-t-metric); font-weight: var(--sl-w-display);
                    line-height: 1; letter-spacing: -.03em; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.sl-metric-label  { font-size: var(--sl-t-metric-label); font-weight: var(--sl-w-medium); line-height: 1.35;
                    color: var(--text-secondary); }

/* Prose should not run the full width of a 27 inch display. */
.sl-measure       { max-width: var(--sl-measure); }
