/* Solis.BackOffice.Portal — shared design tokens (the "solis-*" design system).
   Loaded by every layout, not just auth — anything using --solis-* custom properties (any
   solis-shared/* component, or a screen's own CSS) needs this loaded first. */

/* Border-box everywhere, before any token. Not a preference: content-box means a `width: 100%`
   element with side padding measures wider than the space it was given, and that produced four
   separate overflow bugs during the Leads build alone — a nav that grew a permanent horizontal
   scrollbar, rows sitting 20px past their container. Each was patched where it surfaced, which is
   why a dozen stylesheets carried their own `box-sizing: border-box` line before this rule existed.
   The print sheet already did exactly this, scoped to print.

   The local declarations are deliberately left in place rather than swept up: several are load-
   bearing documentation of a specific bug at a specific element, and re-declaring what is now the
   default costs nothing.

   Inherit rather than a flat `border-box` on the universal selector, so a component that genuinely
   needs content-box can set it on one element and have its subtree follow, instead of fighting a
   rule that re-asserts itself on every descendant. */
*,
*::before,
*::after {
  box-sizing: inherit;
}

/* The theme's ring for any focusable thing that did not state its own. Rings were written per
   class, and every class that missed one fell back to the browser's blue — the date button did.
   :where() keeps this at zero specificity, so any rule a component writes, `outline: none`
   included, still wins. */
:where(:focus-visible) {
  outline: var(--solis-focus-ring);
  outline-offset: var(--solis-focus-ring-offset);
}

/* A button takes its surroundings' text colour where it states none. Safari on an iPad paints such a button's text and
   icons its system blue (the account menu's chevron). :where() keeps this at zero specificity, so a component's colour wins. */
:where(button) {
  color: inherit;
}

html {
  box-sizing: border-box;
}

:root {
  --solis-accent-50: oklch(0.98 0.003 80);
  --solis-accent-200: oklch(0.85 0.005 80);
  --solis-accent-400: oklch(0.65 0.2 45);
  --solis-accent-500: oklch(0.55 0.16 40);
  --solis-accent-600: oklch(0.48 0.18 40);
  --solis-accent-700: oklch(0.32 0.14 35);
  --solis-accent-900: oklch(0.22 0.1 30);

  --solis-text-primary: oklch(0.22 0.01 80);
  --solis-text-secondary: oklch(0.4 0.01 80);
  /* 0.53, not 0.55: muted is the caption colour on three different grounds and only cleared
     4.5:1 on --solis-surface. On --solis-ground it sat at 4.32. Two points of lightness is
     invisible as a design change and takes every ground to 4.7 or better. */
  --solis-text-muted: oklch(0.53 0.01 80);
  --solis-text-on-accent: #fff;
  --solis-text-on-accent-muted: oklch(0.85 0.01 80);

  --solis-border: oklch(0.85 0.005 80);
  --solis-surface: #fff;
  --solis-surface-muted: oklch(0.98 0.003 80);

  /* Every focusable control states this rather than falling back to the browser's own ring — a blue
     outline in the middle of an orange design system. Filled buttons got it during the Messages
     work; this is the same treatment, named once so the rest can share it. */
  --solis-focus-ring: 2px solid var(--solis-accent-400);
  --solis-focus-ring-offset: 2px;

  --solis-danger-500: oklch(0.55 0.2 25);
  --solis-danger-bg: oklch(0.96 0.03 25);
  --solis-danger-border: oklch(0.8 0.1 25);

  --solis-success-500: oklch(0.6 0.15 145);
  --solis-success-bg: oklch(0.96 0.03 145);
  --solis-success-border: oklch(0.8 0.1 145);

  --solis-warn-500: oklch(0.62 0.15 75);
  --solis-warn-bg: oklch(0.96 0.04 85);
  --solis-warn-border: oklch(0.82 0.1 85);

  /* Monospace reserved for true identifiers only — account / customer / ID / registration numbers —
     never for names, addresses, or free text (see the customer detail screen's typography rule). */
  --solis-font: "Inter", system-ui, sans-serif;
  --solis-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* Stat-tile icon-chip hues (icon color + a translucent tint of the same hue for the chip).
     A small semantic palette beyond the single brand accent, for dashboards/summary strips that
     need to tell four tiles apart at a glance. Solid hue + alpha tint, so the one value works on
     any surface; the light/dark split only lifts lightness for dark mode (see below). */
  --solis-ic-accent: oklch(0.6 0.18 45);   --solis-ic-accent-bg: oklch(0.65 0.2 45 / 0.14);
  --solis-ic-blue: oklch(0.55 0.13 250);   --solis-ic-blue-bg: oklch(0.55 0.13 250 / 0.14);
  --solis-ic-green: oklch(0.55 0.14 150);  --solis-ic-green-bg: oklch(0.6 0.15 145 / 0.15);
  --solis-ic-violet: oklch(0.55 0.16 300); --solis-ic-violet-bg: oklch(0.55 0.16 300 / 0.15);
  --solis-ic-teal: oklch(0.55 0.1 195);    --solis-ic-teal-bg: oklch(0.55 0.1 195 / 0.15);
  --solis-ic-rose: oklch(0.55 0.17 355);   --solis-ic-rose-bg: oklch(0.55 0.17 355 / 0.14);
  --solis-ic-slate: oklch(0.45 0.025 260); --solis-ic-slate-bg: oklch(0.45 0.025 260 / 0.15);
  --solis-ic-stone: oklch(0.55 0.05 40);   --solis-ic-stone-bg: oklch(0.55 0.05 40 / 0.15);

  /* Pill text on each hue's tint, and anything else that sets text on one: small bold text needs
     4.5:1, which the icon hues above miss on their own tints. Dark mode lifts each one below. */
  --solis-success-ink: oklch(0.42 0.12 145);
  --solis-warn-ink: oklch(0.44 0.13 75);
  --solis-danger-ink: oklch(0.46 0.16 25);
  --solis-info-ink: oklch(0.42 0.12 255);
  --solis-info-bg: oklch(0.95 0.03 250);
  --solis-accent-ink: var(--solis-accent-600);
  --solis-violet-ink: oklch(0.42 0.14 300);
  --solis-teal-ink: oklch(0.42 0.09 195);
  --solis-rose-ink: oklch(0.45 0.16 355);
  --solis-stone-ink: oklch(0.42 0.055 40);
  /* The glow round a search box while it has focus. */
  --solis-focus-halo: 0 0 0 3px oklch(0.65 0.2 45 / 0.12);

  /* Solis mark (sunburst) colours, pulled straight from the logo — a warm secondary palette for
     moments that want variety beyond the single accent orange (e.g. a gold→red gradient chip).
     Gold is too light for text/large fills on white; reserve it for gradients and glyphs on a fill. */
  --solis-brand-gold: #FFCC07;
  --solis-brand-amber: #F19C24;
  --solis-brand-orange: #ED5225;
  --solis-brand-red: #E92327;

  /* Notification category colors — solid badges with white icon glyphs on top, so lightness is
     capped near --solis-accent-500's own 0.55 (already proven to clear contrast against white
     elsewhere, e.g. .solis-shell__avatar) rather than picked freely per color. Not theme-switched
     (same convention as accent-500/danger-500/success-500 above: a brand/semantic color stays put
     across light/dark, only its background/border tints move). */
  --solis-category-approval: var(--solis-accent-500);
  --solis-category-recert: oklch(0.55 0.17 55);
  /* The recert hue as a glyph on the surface; the badge colour above stays put in dark mode and
     drops near 2:1 there, so this one lifts. */
  --solis-category-recert-ink: oklch(0.55 0.17 55);
  --solis-category-transaction: oklch(0.5 0.14 250);
  --solis-category-system: oklch(0.45 0.02 80);

  /* One ramp. There were twelve distinct radii in the stylesheets against two tokens, so most
     corners were a literal picked by hand — 6 and 7, 11 and 13, sat side by side saying nothing
     different. 50% stays a literal where it means "a circle", which is not a step on a ramp. */
  /* Type ramp. There was none: 27 distinct sizes across the stylesheets, all literals, seven of
     them inside a three-pixel band — which is how a caption ended up at 10.5, 11.5 and 12 depending
     on which component wrote it. Every existing size maps to the nearest step, none moves more
     than 2px. */
  /* Spacing ramp. Every whole number from 1 to 16 was in use, so no gap or inset meant anything
     relative to another. Two-pixel steps through the dense small range, four and eight above it;
     nothing moved more than 2px in the migration. */
  --solis-space-3xs: 2px;
  --solis-space-2xs: 4px;
  --solis-space-xs: 6px;
  --solis-space-sm: 8px;
  --solis-space-md: 10px;
  --solis-space-lg: 12px;
  --solis-space-xl: 14px;
  --solis-space-2xl: 16px;
  --solis-space-3xl: 18px;
  --solis-space-4xl: 20px;
  --solis-space-5xl: 24px;
  --solis-space-6xl: 28px;
  --solis-space-7xl: 32px;
  --solis-space-8xl: 40px;
  --solis-space-9xl: 48px;
  --solis-space-10xl: 60px;
  --solis-space-11xl: 80px;

  --solis-fs-2xs: 10px;
  --solis-fs-xs: 11px;
  --solis-fs-sm: 12px;
  --solis-fs-md: 13px;
  --solis-fs-lg: 14px;
  --solis-fs-xl: 15px;
  --solis-fs-2xl: 17px;
  --solis-fs-3xl: 19px;
  --solis-fs-4xl: 21px;
  --solis-fs-5xl: 24px;
  --solis-fs-6xl: 32px;
  --solis-fs-7xl: 40px;

  --solis-radius-xs: 4px;
  --solis-radius-sm: 6px;
  --solis-radius-md: 8px;
  --solis-radius-lg: 12px;
  --solis-radius-xl: 16px;
  --solis-radius-pill: 999px;

  /* Page widths. Every full-width screen — tables and record pages alike — is one width, so moving
     between screens never shifts the margins; a table wider than it scrolls sideways. Single-purpose
     forms and searches are narrow, because a form that fills a wide screen is harder to read. */
  /* Chart series, in the order a chart assigns them. Validated as a set for colour-blind and
     normal-vision separation between neighbours, in this order, on each theme's surface. No green or
     red among them: those mean good and bad news on this portal, never "series three". */
  --solis-chart-1: #eb6834;
  --solis-chart-2: #2a78d6;
  --solis-chart-3: #eda100;
  --solis-chart-4: #0f95a8;
  --solis-chart-5: #4a3aa7;
  --solis-chart-6: #e87ba4;

  --solis-page-width: 1320px;
  --solis-page-width-narrow: 720px;

  /* A free-text cell in a one-line table (.solis-table__wrap): the widest it grows before it wraps,
     and the narrowest it gives way to before the table scrolls instead. */
  --solis-table-wrap-width: 320px;
  --solis-table-wrap-min-width: 200px;

  /* The app's ground — what the shell paints behind cards. Its own token rather than reusing
     --solis-surface-muted, which the rest of the system uses for muted fills *inside* a card: the
     ground has to sit further from --solis-surface than that to give a white card an edge, and
     deepening the shared token would have darkened every panel and table stripe with it. */
  --solis-ground: oklch(0.96 0.004 80);

  /* Elevation. A shadow is not a hue and doesn't spend the colour budget — it answers "which of
     these surfaces is on top", which a 1px border was leaving to guesswork on a near-white ground.
     Named here because the values were already loose in the codebase: --solis-shadow-sm was being
     referenced with an inline fallback in solis-record.css before it existed anywhere, and the pop
     and modal values were each written out as literals at two or three call sites.
     Dark mode overrides all four rather than inheriting: a translucent warm grey over a dark
     ground is invisible, so those go near-black and heavier. */
  --solis-shadow-sm: 0 1px 2px oklch(0.2 0.01 80 / 0.05);
  --solis-shadow-card: 0 1px 2px oklch(0.2 0.02 60 / 0.05), 0 4px 12px oklch(0.2 0.02 60 / 0.06);
  --solis-shadow-pop: 0 10px 30px oklch(0.2 0.02 60 / 0.18);
  --solis-shadow-modal: 0 24px 60px rgb(0 0 0 / 0.3);

  /* Always dark regardless of the app's own light/dark theme — same convention as a native OS
     tooltip and most design systems (GitHub, Slack): a tooltip is a temporary overlay, not page
     chrome, so it doesn't need to track the surface underneath it. */
  --solis-tooltip-bg: oklch(0.2 0.01 80);
  --solis-tooltip-text: #fff;

  /* White in both themes: an email preview stands for a mail app's page, and an email that sets no background of its
     own is read on white there. */
  --solis-email-canvas: #fff;

  /* Sidebar-only "on accent" palette — solid accent background with light text on top. Not a
     reuse of --solis-accent-700/-900: those darken by *also* drifting hue from 40 toward 30-35
     (see solis-tokens.css), which reads as a desaturated maroon/brown rather than the brand's
     actual orange once it's covering a whole panel instead of a small chip — this stays on
     accent-500's hue (40) and just drops lightness, the same way a UI would darken a brand color
     by keeping its hue fixed. Scoped to these tokens rather than reusing
     --solis-text-on-accent/-muted (those are sized for small chips like .solis-shell__avatar, not
     a whole panel's worth of body text). Lightness picked at 0.50, not accent-500's own 0.55 —
     chosen empirically against rendered contrast: 0.50 keeps sidebar nav text at ~5.57:1 (clear of
     WCAG AA's 4.5:1 for normal text), while 0.55 (an exact match to the accent/avatar/button
     color) pulls the whole ladder down by roughly half a point and leaves the muted tier below AA.

     Both text tiers sit high in lightness and close together (0.95/0.89), which is what a panel
     this light forces: the muted tier is real body copy — sub-menu links, not just decoration —
     and it has to clear 4.5:1 against the panel, which leaves only ~0.06 of lightness between the
     two. Size, weight, letter-spacing and indent carry that hierarchy, not the color gap. */
  --solis-sidebar-bg: oklch(0.5 0.17 40);
  /* Same recipe as dark, at a fraction of the range: ±0.04 around the base rather than dark's
     0.42→0.28. Light mode has no defect to fix — the panel sits 0.48 below the canvas and already
     reads as a solid block — so this is only enough to stop it being a dead flat field, and it
     keeps the element behaving the same way in both themes instead of needing a comment to explain
     why one of them is different.

     It only ever darkens: the top stop is the base, and the gradient falls away from there. Going
     the other way — a lighter head — was measured at 3.90 against the 11px section labels, under
     the 4.5 AA floor, because those labels already sit at 4.63 on the flat panel with almost no
     margin. Darkening downward keeps that top figure exactly as it is today and improves every
     stop below it, so the wash cannot cost contrast anywhere. */
  --solis-sidebar-wash: linear-gradient(168deg, oklch(0.5 0.17 40) 0%, oklch(0.45 0.16 38) 70%);
  --solis-sidebar-text: oklch(0.95 0.012 55);
  --solis-sidebar-text-muted: oklch(0.89 0.02 55);
  --solis-sidebar-border: oklch(0.34 0.14 40);

  /* Hover/press tint. Darkens the panel rather than the usual white-overlay lightening: the panel
     is only mid-dark, so a white overlay pulls it toward the text sitting on it — a 12% white wash
     takes the muted tier from 4.63:1 to 3.71:1, i.e. below AA on exactly the row the pointer is
     on — and it desaturates the brand orange to a washed pink. Black at 14% moves the other way
     (both tiers gain about a point) and holds the hue. */
  /* Lifts the panel rather than darkening it. An accent tint — the treatment the menus on white
     surfaces get — is invisible here, because this panel is the accent, and black at 14% was the
     inverse move: it muddied the orange and barely registered once dark mode's panel deepened.

     A light *warm* overlay rather than white: white washes the hue out (it drove the blue channel
     from 0 to 33 on the dark rail, turning the lift pink-grey), where this keeps it orange at 13.

     Per-theme alpha, because one value does not give one result. The dark panel is deeper, so the
     same overlay moves it further: at 0.13 white the step measured 1.26 in light against 1.32-1.39
     in dark. These two land both themes on ~1.25. Dark still spans a small range top-to-bottom
     because that panel is a gradient — 1.22 at the head, 1.27 at the foot. */
  --solis-sidebar-hover: oklch(0.78 0.14 48 / 0.2);

  /* Active pill. Tracks --solis-surface-muted specifically (not --solis-surface) because that is
     what the content area behind .solis-shell__content actually paints — the pill runs out to the
     sidebar's edge to read as continuous with the page canvas, and a --solis-surface pill left a
     visible step against it in dark mode (0.19 vs 0.23). Its text needs a per-theme value to
     match: the brand orange reads 6.08:1 on the light pill but only 2.86:1 on the dark one, so
     dark mode lightens it (see the theme blocks below). */
  --solis-sidebar-active-bg: var(--solis-surface-muted);
  --solis-sidebar-active-bg-hover: var(--solis-surface);
  --solis-sidebar-active-text: var(--solis-sidebar-bg);

  /* ---- Things that sit over the page ----
     Three dimming layers, not one value per screen: light for a panel that overlaps the page it
     leaves in place (the sidebar's peek), standard for a dialog, a drawer or the idle warning, and
     heavy for the blocking loader. Text over a scrim is white in both themes. */
  --solis-scrim-light: rgb(0 0 0 / 0.3);
  --solis-scrim: rgb(0 0 0 / 0.45);
  --solis-scrim-heavy: rgb(0 0 0 / 0.62);
  --solis-on-scrim: #fff;
  --solis-on-scrim-muted: rgb(255 255 255 / 0.55);
  --solis-text-shadow-on-scrim: 0 1px 4px rgb(0 0 0 / 0.4);

  /* Shadows of things that float, named for what floats. The cards' own are above. */
  --solis-shadow-lift: 0 1px 2px rgb(0 0 0 / 0.12);
  --solis-shadow-knob: 0 1px 2px rgb(0 0 0 / 0.2);
  --solis-shadow-tip: 0 2px 8px rgb(0 0 0 / 0.18);
  --solis-shadow-panel: 0 8px 24px rgb(0 0 0 / 0.12);
  --solis-shadow-side: 8px 0 28px rgb(0 0 0 / 0.22);
  --solis-shadow-alert: 0 12px 32px rgb(0 0 0 / 0.24);
  --solis-shadow-drawer: -18px 0 50px oklch(0.2 0.02 60 / 0.18);
  --solis-shadow-seg-on: 0 1px 2px oklch(0.4 0.14 40 / 0.35);

  /* The accent and danger at a whisper, for a row under the pointer. */
  --solis-accent-wash: oklch(0.55 0.16 40 / 0.09);
  --solis-accent-wash-strong: oklch(0.55 0.16 40 / 0.13);
  --solis-danger-wash: oklch(0.55 0.2 25 / 0.09);

  /* White over the sidebar's accent panel: the search field's resting, focused and hovered
     steps, the match highlight and the scrollbar. The same in both themes. */
  --solis-sidebar-field-bg: rgb(255 255 255 / 0.12);
  --solis-sidebar-field-edge: rgb(255 255 255 / 0.16);
  --solis-sidebar-field-bg-focus: rgb(255 255 255 / 0.18);
  --solis-sidebar-field-edge-focus: rgb(255 255 255 / 0.4);
  --solis-sidebar-scrollbar: rgb(255 255 255 / 0.3);
  --solis-sidebar-scrollbar-hover: rgb(255 255 255 / 0.5);

  /* The sign-in photo panel's glows and carousel dots, and the biometric button's ring. */
  --solis-auth-glow-bottom: radial-gradient(circle, oklch(0.65 0.2 45 / 0.65) 0%, oklch(0.65 0.2 45 / 0) 70%);
  --solis-auth-glow-top: radial-gradient(circle, oklch(0.6 0.19 40 / 0.45) 0%, oklch(0.6 0.19 40 / 0) 70%);
  --solis-auth-dot: oklch(1 0 0 / 0.35);
  --solis-auth-ring: oklch(0.55 0.16 40 / 0.12);

  /* A switch's knob, and the two export buttons' conventional file colours. */
  --solis-switch-knob: #fff;
  --solis-file-xls: oklch(0.52 0.13 150);
  --solis-file-pdf: oklch(0.53 0.18 27);

  /* The date-range picker's band between its two ends; deeper in dark mode. */
  --solis-drp-band: oklch(0.93 0.05 45);
}

/* Bootstrap is gone (frontend-styling.md) — this replaces the one remaining Bootstrap utility
   class reference (Error.cshtml's text-danger), not reintroducing a general utility-class set. */
.solis-text-danger {
  color: var(--solis-danger-500);
}

/* Global tooltip — CSS-only, attribute-driven: add data-tooltip="label" to any element (it must
   be the thing that receives hover/focus, e.g. the button itself, not a wrapper). Default
   placement is above, centered — fine for most controls, but wrong for anything hugging the top
   of the viewport (the topbar's icon buttons): there's no room above them, so the bubble renders
   clipped by the viewport edge instead of just not showing. Add data-tooltip-position="bottom"
   there, or "right" for icon rails/sidebars where the control sits at the left edge and an
   above/below tooltip would run off-screen or collide with neighboring rows. "left" is the mirror
   of that, for a control near the viewport's right edge; "top" is the default, written out. Pointer-events: none
   on the bubble so it never intercepts the click that would dismiss it. The transition-delay (not
   a JS setTimeout) is what gives this the same "pause before it appears" feel as a native tooltip
   without reimplementing the timer in TS. */
[data-tooltip] {
  position: relative;
}

[data-tooltip]::after,
[data-tooltip]::before {
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.12s ease, transform 0.12s ease;
  z-index: 1000;
}


[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 7px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  background: var(--solis-tooltip-bg);
  color: var(--solis-tooltip-text);
  /* Its own face, not the element's: a tooltip on an account number is a sentence, not a number. */
  font-family: var(--solis-font);
  font-size: var(--solis-fs-sm);
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
  padding: var(--solis-space-2xs) var(--solis-space-sm);
  border-radius: var(--solis-radius-sm);
  box-shadow: 0 2px 8px rgb(0 0 0 / 0.18);
}

[data-tooltip]::before {
  content: "";
  position: absolute;
  bottom: calc(100% + 2px);
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--solis-tooltip-bg);
}
/* An empty label draws nothing. A view that means "no tooltip on this one" writes the attribute
   from a nullable expression and expects Razor to drop it — which it does for some attributes and
   not for data-*, handing through data-tooltip="" instead. That still matches [data-tooltip], so
   the result was a blank bubble on hover; three views were already doing it, the account menu
   most visibly, where every enabled item flashed an empty box. Guarded here so the component
   decides, rather than every caller having to get Razor's omission rules right. */
[data-tooltip=""]::after,
[data-tooltip=""]::before {
  content: none;
}

/* A control whose bubble floatingTooltip.ts draws, because a scrolling box around it would clip this one, opts out of this
   one with data-tooltip-floating, so the two are never drawn together. */
[data-tooltip][data-tooltip-floating]::after,
[data-tooltip][data-tooltip-floating]::before {
  display: none;
}

/* Carries a tooltip on behalf of a control that cannot receive hover itself — a disabled button
   gets no mouse events, so the explanation for why it is disabled is exactly the tooltip that
   could never be shown. Lays out as its child so wrapping one does not move it. */
.solis-tooltip-host {
  display: inline-flex;
}

[data-tooltip]:hover::after,
[data-tooltip]:hover::before,
[data-tooltip]:focus-visible::after,
[data-tooltip]:focus-visible::before {
  opacity: 1;
  visibility: visible;
  transition-delay: 0.35s;
}

[data-tooltip]:hover::after,
[data-tooltip]:focus-visible::after {
  transform: translateX(-50%) translateY(0);
}

/* A sentence rather than a label: wrapped to a readable measure instead of one long line. */
[data-tooltip][data-tooltip-wrap]::after {
  white-space: normal;
  width: max-content;
  max-width: 260px;
  text-align: left;
  line-height: 1.4;
  /* Set as a sentence even on a host styled as a label — a pill's capitals and tracking. */
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
}

/* Anchored to the control's own right edge, for the last control in a row. The bubble keeps its
   layout box even while hidden (visibility, not display — the transition needs it), so a centered
   one on a control near a container's edge widens that container and can hand the page a
   horizontal scrollbar that nothing visible accounts for. */
[data-tooltip][data-tooltip-align="right"]::after {
  left: auto;
  right: 0;
  transform: translateX(0) translateY(4px);
}

[data-tooltip][data-tooltip-align="right"]:hover::after,
[data-tooltip][data-tooltip-align="right"]:focus-visible::after {
  transform: translateX(0) translateY(0);
}

[data-tooltip][data-tooltip-align="right"]::before {
  left: auto;
  right: 12px;
  transform: none;
}

/* The mirror, for the first control in a row: centred on a table's first column, the bubble ran out
   past the card's left edge and under the sidebar. */
[data-tooltip][data-tooltip-align="left"]::after {
  left: 0;
  transform: translateX(0) translateY(4px);
}

[data-tooltip][data-tooltip-align="left"]:hover::after,
[data-tooltip][data-tooltip-align="left"]:focus-visible::after {
  transform: translateX(0) translateY(0);
}

[data-tooltip][data-tooltip-align="left"]::before {
  left: 12px;
  transform: none;
}

[data-tooltip][data-tooltip-position="right"]::after {
  bottom: auto;
  top: 50%;
  left: calc(100% + 9px);
  transform: translateY(-50%) translateX(-4px);
}

[data-tooltip][data-tooltip-position="right"]::before {
  bottom: auto;
  top: 50%;
  left: calc(100% + 3px);
  transform: translateY(-50%);
  border-top-color: transparent;
  border-right-color: var(--solis-tooltip-bg);
}

[data-tooltip][data-tooltip-position="right"]:hover::after,
[data-tooltip][data-tooltip-position="right"]:focus-visible::after {
  transform: translateY(-50%) translateX(0);
}

[data-tooltip][data-tooltip-position="bottom"]::after {
  bottom: auto;
  top: calc(100% + 7px);
  transform: translateX(-50%) translateY(-4px);
}

[data-tooltip][data-tooltip-position="bottom"]::before {
  bottom: auto;
  top: calc(100% + 2px);
  border-top-color: transparent;
  border-bottom-color: var(--solis-tooltip-bg);
}

[data-tooltip][data-tooltip-position="bottom"]:hover::after,
[data-tooltip][data-tooltip-position="bottom"]:focus-visible::after {
  transform: translateX(-50%) translateY(0);
}

/* Below and anchored right, for the last control in the top bar (the bell): centred, its hidden bubble ran past the
   window and a menu opening on the page scrolled the shell sideways to make room. */
[data-tooltip][data-tooltip-position="bottom"][data-tooltip-align="right"]::after { transform: translateX(0) translateY(-4px); }
[data-tooltip][data-tooltip-position="bottom"][data-tooltip-align="right"]:hover::after,
[data-tooltip][data-tooltip-position="bottom"][data-tooltip-align="right"]:focus-visible::after { transform: translateX(0) translateY(0); }

/* Mirror of "right", for a control whose own container ends just past its right edge — a menu item
   inside a dropdown panel pinned to the viewport's right, where "right" would leave the bubble
   off-screen and the default would lay it over the row above. */
[data-tooltip][data-tooltip-position="left"]::after {
  bottom: auto;
  top: 50%;
  left: auto;
  right: calc(100% + 9px);
  transform: translateY(-50%) translateX(4px);
}

[data-tooltip][data-tooltip-position="left"]::before {
  bottom: auto;
  top: 50%;
  left: auto;
  right: calc(100% + 3px);
  transform: translateY(-50%);
  border-top-color: transparent;
  border-left-color: var(--solis-tooltip-bg);
}

[data-tooltip][data-tooltip-position="left"]:hover::after,
[data-tooltip][data-tooltip-position="left"]:focus-visible::after {
  transform: translateY(-50%) translateX(0);
}

/* Above is already the default, so this exists to be written down rather than to change anything:
   a screen that states its placement reads the same as its neighbours that had to state theirs,
   and it restores the default explicitly if a shared partial ever sets a different one. */
[data-tooltip][data-tooltip-position="top"]::after {
  top: auto;
  bottom: calc(100% + 7px);
  left: 50%;
  right: auto;
  transform: translateX(-50%) translateY(4px);
}

[data-tooltip][data-tooltip-position="top"]::before {
  top: auto;
  bottom: calc(100% + 2px);
  left: 50%;
  right: auto;
  transform: translateX(-50%);
  border-bottom-color: transparent;
  border-left-color: transparent;
  border-right-color: transparent;
  border-top-color: var(--solis-tooltip-bg);
}

[data-tooltip][data-tooltip-position="top"]:hover::after,
[data-tooltip][data-tooltip-position="top"]:focus-visible::after {
  transform: translateX(-50%) translateY(0);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --solis-text-primary: oklch(0.95 0.005 80);
    --solis-text-secondary: oklch(0.78 0.008 80);
    --solis-text-muted: oklch(0.63 0.01 80);
    /* accent-50 gets a dark variant and this did not, so accent-600 text on it — the date range
       picker's own trigger, among others — came out at 2.1:1. Same family as --solis-ic-accent,
       which is the accent already tuned for a dark ground. */
    --solis-accent-600: oklch(0.72 0.16 45);
    --solis-border: oklch(0.32 0.008 80);
    --solis-surface: oklch(0.19 0.006 80);
    --solis-surface-muted: oklch(0.23 0.006 80);
    --solis-ground: oklch(0.15 0.006 80);
    --solis-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.4);
    --solis-shadow-card: 0 1px 2px rgb(0 0 0 / 0.4), 0 4px 12px rgb(0 0 0 / 0.3);
    --solis-shadow-pop: 0 10px 30px rgb(0 0 0 / 0.5);
    --solis-shadow-modal: 0 24px 60px rgb(0 0 0 / 0.6);
    /* Was left undefined here — stayed pinned to its near-white light value, so anything using it
       as a background (unread notification rows/items) rendered a near-white box with light,
       dark-mode text on top of it, unreadable. Same low-lightness-tint convention as danger-bg/
       success-bg below, just at the accent hue (40) instead of danger's (25) or success's (145). */
    --solis-accent-50: oklch(0.28 0.06 40);
    --solis-danger-bg: oklch(0.28 0.06 25);
    --solis-danger-border: oklch(0.4 0.1 25);
    --solis-success-bg: oklch(0.28 0.06 145);
    --solis-success-border: oklch(0.4 0.1 145);
    --solis-warn-bg: oklch(0.30 0.06 85);
    --solis-warn-border: oklch(0.44 0.1 85);
    --solis-ic-accent: oklch(0.78 0.16 50);  --solis-ic-accent-bg: oklch(0.65 0.2 45 / 0.2);
    --solis-ic-blue: oklch(0.75 0.12 250);   --solis-ic-blue-bg: oklch(0.6 0.13 250 / 0.2);
    --solis-ic-green: oklch(0.8 0.15 150);   --solis-ic-green-bg: oklch(0.6 0.15 145 / 0.2);
    --solis-ic-violet: oklch(0.78 0.14 300); --solis-ic-violet-bg: oklch(0.6 0.16 300 / 0.2);
    --solis-ic-teal: oklch(0.8 0.1 195);     --solis-ic-teal-bg: oklch(0.6 0.1 195 / 0.2);
    --solis-ic-rose: oklch(0.8 0.13 355);    --solis-ic-rose-bg: oklch(0.6 0.17 355 / 0.2);
    --solis-ic-slate: oklch(0.78 0.02 260);  --solis-ic-slate-bg: oklch(0.6 0.025 260 / 0.2);
    --solis-ic-stone: oklch(0.8 0.05 40);    --solis-ic-stone-bg: oklch(0.6 0.05 40 / 0.2);
    --solis-chart-1: #d95926;
    --solis-chart-2: #3987e5;
    --solis-chart-3: #c98500;
    --solis-chart-4: #1498ab;
    --solis-chart-5: #9085e9;
    --solis-chart-6: #d55181;
    --solis-success-ink: oklch(0.84 0.15 150);
    --solis-warn-ink: oklch(0.85 0.14 90);
    --solis-danger-ink: oklch(0.82 0.14 28);
    --solis-info-ink: oklch(0.83 0.11 250);
    --solis-info-bg: oklch(0.28 0.05 255);
    --solis-accent-ink: oklch(0.8 0.15 50);
    --solis-violet-ink: var(--solis-ic-violet);
    --solis-teal-ink: var(--solis-ic-teal);
    --solis-rose-ink: var(--solis-ic-rose);
    --solis-stone-ink: var(--solis-ic-stone);
    --solis-category-recert-ink: oklch(0.75 0.15 60);

    /* Dark mode deepens the panel on the same hue, at slightly lower chroma. The sidebar is the largest
       single block of color in the app, and the problem it solves is not brightness on its own but a
       flip in polarity: in light mode it sits 0.48 *below* the canvas and recedes, so at 0.44 against
       a 0.23 canvas it sat 0.21 *above* and advanced — the same element receding in one theme and
       pressing forward in the other, pulling the eye to navigation on every dark screen.

       0.34 puts it ~0.11 above the canvas: still unmistakably the brand orange and still a distinct
       panel, but sitting with the theme rather than lit against it. The active pill stays bright, so it
       remains the one thing in the region actually signalling something. Every text tier gains contrast
       as a side effect.

       Flat, that deepened tone read muddy — a large, low-chroma slab with nothing happening in it. The
       wash is the move the record hero already makes (solis-record.css: accent into surface), turned
       vertical: warmer at the top where the logo sits, sinking toward the canvas by the foot of the nav.
       The bottom stop lands at 0.31 rather than lower — the canvas is 0.23, and at 0.28 the foot of the
       panel sat close enough to it that the sidebar read as fading out instead of ending.
       Light mode takes no wash because its panel sits *below* the canvas and already reads as a solid
       block — it is a large area sitting *above* the canvas that needs the depth.

       Set in this block for the "system" setting and again in the attribute block below for an
       explicit toggle, as every token here is. */
    --solis-sidebar-bg: oklch(0.34 0.13 40);
    --solis-sidebar-wash: linear-gradient(168deg, oklch(0.42 0.15 40) 0%, oklch(0.31 0.11 38) 65%);
    --solis-sidebar-hover: oklch(0.78 0.14 48 / 0.13);
    --solis-sidebar-border: oklch(0.27 0.1 40);
    --solis-sidebar-active-bg-hover: oklch(0.28 0.006 80);
    --solis-sidebar-active-text: oklch(0.72 0.16 50);
    --solis-drp-band: oklch(0.33 0.07 40);
  }
}

:root[data-theme="dark"] {
  --solis-text-primary: oklch(0.95 0.005 80);
  --solis-text-secondary: oklch(0.78 0.008 80);
  --solis-text-muted: oklch(0.63 0.01 80);
  --solis-accent-600: oklch(0.72 0.16 45);
  --solis-border: oklch(0.32 0.008 80);
  --solis-surface: oklch(0.19 0.006 80);
  --solis-surface-muted: oklch(0.23 0.006 80);
  --solis-ground: oklch(0.15 0.006 80);
  --solis-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.4);
  --solis-shadow-card: 0 1px 2px rgb(0 0 0 / 0.4), 0 4px 12px rgb(0 0 0 / 0.3);
  --solis-shadow-pop: 0 10px 30px rgb(0 0 0 / 0.5);
  --solis-shadow-modal: 0 24px 60px rgb(0 0 0 / 0.6);
  --solis-accent-50: oklch(0.28 0.06 40);
  --solis-danger-bg: oklch(0.28 0.06 25);
  --solis-danger-border: oklch(0.4 0.1 25);
  --solis-success-bg: oklch(0.28 0.06 145);
  --solis-success-border: oklch(0.4 0.1 145);
  --solis-warn-bg: oklch(0.30 0.06 85);
  --solis-warn-border: oklch(0.44 0.1 85);
  --solis-ic-accent: oklch(0.78 0.16 50);  --solis-ic-accent-bg: oklch(0.65 0.2 45 / 0.2);
  --solis-ic-blue: oklch(0.75 0.12 250);   --solis-ic-blue-bg: oklch(0.6 0.13 250 / 0.2);
  --solis-ic-green: oklch(0.8 0.15 150);   --solis-ic-green-bg: oklch(0.6 0.15 145 / 0.2);
  --solis-ic-violet: oklch(0.78 0.14 300); --solis-ic-violet-bg: oklch(0.6 0.16 300 / 0.2);
  --solis-ic-teal: oklch(0.8 0.1 195);     --solis-ic-teal-bg: oklch(0.6 0.1 195 / 0.2);
  --solis-ic-rose: oklch(0.8 0.13 355);    --solis-ic-rose-bg: oklch(0.6 0.17 355 / 0.2);
  --solis-ic-slate: oklch(0.78 0.02 260);  --solis-ic-slate-bg: oklch(0.6 0.025 260 / 0.2);
  --solis-ic-stone: oklch(0.8 0.05 40);    --solis-ic-stone-bg: oklch(0.6 0.05 40 / 0.2);
  --solis-chart-1: #d95926;
  --solis-chart-2: #3987e5;
  --solis-chart-3: #c98500;
  --solis-chart-4: #1498ab;
  --solis-chart-5: #9085e9;
  --solis-chart-6: #d55181;
  --solis-success-ink: oklch(0.84 0.15 150);
  --solis-warn-ink: oklch(0.85 0.14 90);
  --solis-danger-ink: oklch(0.82 0.14 28);
  --solis-info-ink: oklch(0.83 0.11 250);
  --solis-info-bg: oklch(0.28 0.05 255);
  --solis-accent-ink: oklch(0.8 0.15 50);
  --solis-violet-ink: var(--solis-ic-violet);
  --solis-teal-ink: var(--solis-ic-teal);
  --solis-rose-ink: var(--solis-ic-rose);
  --solis-stone-ink: var(--solis-ic-stone);
  --solis-category-recert-ink: oklch(0.75 0.15 60);


  /* The sidebar palette, as in the "system" block above. */
  --solis-sidebar-bg: oklch(0.34 0.13 40);
  --solis-sidebar-wash: linear-gradient(168deg, oklch(0.42 0.15 40) 0%, oklch(0.31 0.11 38) 65%);
  --solis-sidebar-hover: oklch(0.78 0.14 48 / 0.13);
  --solis-sidebar-border: oklch(0.27 0.1 40);
  --solis-sidebar-active-bg-hover: oklch(0.28 0.006 80);
  --solis-sidebar-active-text: oklch(0.72 0.16 50);
  --solis-drp-band: oklch(0.33 0.07 40);
}

/* A touch screen draws no tooltips. With no hover to end, a tapped control kept its bubble until the next tap elsewhere, and
   a drawer's focused close button showed its own beside it (an iPad's menu read "Open Menu" and "Close Menu" at once). */
@media (hover: none) {
  [data-tooltip]::after,
  [data-tooltip]::before {
    display: none;
  }
}
