*, ::before, ::after {
  --tw-border-spacing-x: 0;
  --tw-border-spacing-y: 0;
  --tw-translate-x: 0;
  --tw-translate-y: 0;
  --tw-rotate: 0;
  --tw-skew-x: 0;
  --tw-skew-y: 0;
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  --tw-pan-x:  ;
  --tw-pan-y:  ;
  --tw-pinch-zoom:  ;
  --tw-scroll-snap-strictness: proximity;
  --tw-gradient-from-position:  ;
  --tw-gradient-via-position:  ;
  --tw-gradient-to-position:  ;
  --tw-ordinal:  ;
  --tw-slashed-zero:  ;
  --tw-numeric-figure:  ;
  --tw-numeric-spacing:  ;
  --tw-numeric-fraction:  ;
  --tw-ring-inset:  ;
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: rgb(59 130 246 / 0.5);
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  --tw-blur:  ;
  --tw-brightness:  ;
  --tw-contrast:  ;
  --tw-grayscale:  ;
  --tw-hue-rotate:  ;
  --tw-invert:  ;
  --tw-saturate:  ;
  --tw-sepia:  ;
  --tw-drop-shadow:  ;
  --tw-backdrop-blur:  ;
  --tw-backdrop-brightness:  ;
  --tw-backdrop-contrast:  ;
  --tw-backdrop-grayscale:  ;
  --tw-backdrop-hue-rotate:  ;
  --tw-backdrop-invert:  ;
  --tw-backdrop-opacity:  ;
  --tw-backdrop-saturate:  ;
  --tw-backdrop-sepia:  ;
  --tw-contain-size:  ;
  --tw-contain-layout:  ;
  --tw-contain-paint:  ;
  --tw-contain-style:  ;
}

::backdrop {
  --tw-border-spacing-x: 0;
  --tw-border-spacing-y: 0;
  --tw-translate-x: 0;
  --tw-translate-y: 0;
  --tw-rotate: 0;
  --tw-skew-x: 0;
  --tw-skew-y: 0;
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  --tw-pan-x:  ;
  --tw-pan-y:  ;
  --tw-pinch-zoom:  ;
  --tw-scroll-snap-strictness: proximity;
  --tw-gradient-from-position:  ;
  --tw-gradient-via-position:  ;
  --tw-gradient-to-position:  ;
  --tw-ordinal:  ;
  --tw-slashed-zero:  ;
  --tw-numeric-figure:  ;
  --tw-numeric-spacing:  ;
  --tw-numeric-fraction:  ;
  --tw-ring-inset:  ;
  --tw-ring-offset-width: 0px;
  --tw-ring-offset-color: #fff;
  --tw-ring-color: rgb(59 130 246 / 0.5);
  --tw-ring-offset-shadow: 0 0 #0000;
  --tw-ring-shadow: 0 0 #0000;
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  --tw-blur:  ;
  --tw-brightness:  ;
  --tw-contrast:  ;
  --tw-grayscale:  ;
  --tw-hue-rotate:  ;
  --tw-invert:  ;
  --tw-saturate:  ;
  --tw-sepia:  ;
  --tw-drop-shadow:  ;
  --tw-backdrop-blur:  ;
  --tw-backdrop-brightness:  ;
  --tw-backdrop-contrast:  ;
  --tw-backdrop-grayscale:  ;
  --tw-backdrop-hue-rotate:  ;
  --tw-backdrop-invert:  ;
  --tw-backdrop-opacity:  ;
  --tw-backdrop-saturate:  ;
  --tw-backdrop-sepia:  ;
  --tw-contain-size:  ;
  --tw-contain-layout:  ;
  --tw-contain-paint:  ;
  --tw-contain-style:  ;
}/*
! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com
*//*
1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
*/

*,
::before,
::after {
  box-sizing: border-box; /* 1 */
  border-width: 0; /* 2 */
  border-style: solid; /* 2 */
  border-color: #e5e7eb; /* 2 */
}

::before,
::after {
  --tw-content: '';
}

/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
3. Use a more readable tab size.
4. Use the user's configured `sans` font-family by default.
5. Use the user's configured `sans` font-feature-settings by default.
6. Use the user's configured `sans` font-variation-settings by default.
7. Disable tap highlights on iOS
*/

html,
:host {
  line-height: 1.5; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
  -moz-tab-size: 4; /* 3 */
  -o-tab-size: 4;
     tab-size: 4; /* 3 */
  font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 4 */
  font-feature-settings: normal; /* 5 */
  font-variation-settings: normal; /* 6 */
  -webkit-tap-highlight-color: transparent; /* 7 */
}

/*
1. Remove the margin in all browsers.
2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
*/

body {
  margin: 0; /* 1 */
  line-height: inherit; /* 2 */
}

/*
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
3. Ensure horizontal rules are visible by default.
*/

hr {
  height: 0; /* 1 */
  color: inherit; /* 2 */
  border-top-width: 1px; /* 3 */
}

/*
Add the correct text decoration in Chrome, Edge, and Safari.
*/

abbr:where([title]) {
  -webkit-text-decoration: underline dotted;
          text-decoration: underline dotted;
}

/*
Remove the default font size and weight for headings.
*/

h1,
h2,
h3,
h4,
h5,
h6 {
  font-size: inherit;
  font-weight: inherit;
}

/*
Reset links to optimize for opt-in styling instead of opt-out.
*/

a {
  color: inherit;
  text-decoration: inherit;
}

/*
Add the correct font weight in Edge and Safari.
*/

b,
strong {
  font-weight: bolder;
}

/*
1. Use the user's configured `mono` font-family by default.
2. Use the user's configured `mono` font-feature-settings by default.
3. Use the user's configured `mono` font-variation-settings by default.
4. Correct the odd `em` font sizing in all browsers.
*/

code,
kbd,
samp,
pre {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; /* 1 */
  font-feature-settings: normal; /* 2 */
  font-variation-settings: normal; /* 3 */
  font-size: 1em; /* 4 */
}

/*
Add the correct font size in all browsers.
*/

small {
  font-size: 80%;
}

/*
Prevent `sub` and `sup` elements from affecting the line height in all browsers.
*/

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/*
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
3. Remove gaps between table borders by default.
*/

table {
  text-indent: 0; /* 1 */
  border-color: inherit; /* 2 */
  border-collapse: collapse; /* 3 */
}

/*
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
3. Remove default padding in all browsers.
*/

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-feature-settings: inherit; /* 1 */
  font-variation-settings: inherit; /* 1 */
  font-size: 100%; /* 1 */
  font-weight: inherit; /* 1 */
  line-height: inherit; /* 1 */
  letter-spacing: inherit; /* 1 */
  color: inherit; /* 1 */
  margin: 0; /* 2 */
  padding: 0; /* 3 */
}

/*
Remove the inheritance of text transform in Edge and Firefox.
*/

button,
select {
  text-transform: none;
}

/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Remove default button styles.
*/

button,
input:where([type='button']),
input:where([type='reset']),
input:where([type='submit']) {
  -webkit-appearance: button; /* 1 */
  background-color: transparent; /* 2 */
  background-image: none; /* 2 */
}

/*
Use the modern Firefox focus style for all focusable elements.
*/

:-moz-focusring {
  outline: auto;
}

/*
Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
*/

:-moz-ui-invalid {
  box-shadow: none;
}

/*
Add the correct vertical alignment in Chrome and Firefox.
*/

progress {
  vertical-align: baseline;
}

/*
Correct the cursor style of increment and decrement buttons in Safari.
*/

::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
  height: auto;
}

/*
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/

[type='search'] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/*
Remove the inner padding in Chrome and Safari on macOS.
*/

::-webkit-search-decoration {
  -webkit-appearance: none;
}

/*
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to `inherit` in Safari.
*/

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/*
Add the correct display in Chrome and Safari.
*/

summary {
  display: list-item;
}

/*
Removes the default spacing and border for appropriate elements.
*/

blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
  margin: 0;
}

fieldset {
  margin: 0;
  padding: 0;
}

legend {
  padding: 0;
}

ol,
ul,
menu {
  list-style: none;
  margin: 0;
  padding: 0;
}

/*
Reset default styling for dialogs.
*/
dialog {
  padding: 0;
}

/*
Prevent resizing textareas horizontally by default.
*/

textarea {
  resize: vertical;
}

/*
1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
2. Set the default placeholder color to the user's configured gray 400 color.
*/

input::-moz-placeholder, textarea::-moz-placeholder {
  opacity: 1; /* 1 */
  color: #9ca3af; /* 2 */
}

input::placeholder,
textarea::placeholder {
  opacity: 1; /* 1 */
  color: #9ca3af; /* 2 */
}

/*
Set the default cursor for buttons.
*/

button,
[role="button"] {
  cursor: pointer;
}

/*
Make sure disabled buttons don't get the pointer cursor.
*/
:disabled {
  cursor: default;
}

/*
1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
   This can trigger a poorly considered lint error in some tools but is included by design.
*/

img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
  display: block; /* 1 */
  vertical-align: middle; /* 2 */
}

/*
Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
*/

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

/* Make elements with the HTML hidden attribute stay hidden by default */
[hidden]:where(:not([hidden="until-found"])) {
  display: none;
}
  :root {
    --radius: 1rem;
    /* Enhanced High-Contrast Accessible Light Theme: #FAF9F7 / #F6F4F2 */
    --background: 0.98 0.005 60;
    --foreground: 0.15 0 0; /* Darkened from 0.22 to #222 equivalent for better contrast */
    --card: 0.965 0.005 60;
    --card-foreground: 0.15 0 0; /* Darkened for better contrast */
    --popover: 0.965 0.005 60;
    --popover-foreground: 0.15 0 0; /* Darkened for better contrast */
    --primary: 0.15 0 0; /* Darkened for better contrast */
    --primary-foreground: 0.985 0 0;
    --secondary: 0.95 0.005 60;
    --secondary-foreground: 0.15 0 0; /* Darkened for better contrast */
    --muted: 0.93 0.005 60;
    --muted-foreground: 0.45 0 0; /* Darkened from 0.55 for better contrast */
    --accent: 0.65 0.2 40; /* Strengthened chroma from 0.19 to 0.20 for better visibility */
    --accent-foreground: 0.985 0 0;
    /* FASE 1 accent variables — central orange accent (#E8630A) and its variants.
       --accent-hex: solid fills. --accent-rgb: rgb triplet for rgba()/glow usage.
       --accent-dim: dark orange (#4a2400) for filled backgrounds. */
    --accent-hex: #e8630a;
    --accent-rgb: 232, 99, 10;
    --accent-dim: #4a2400;
    --destructive: 0.577 0.245 27.325;
    --destructive-foreground: 0.985 0 0;
    --border: 0.8 0.005 60; /* Darkened from 0.86 for better definition */
    --input: 0.94 0.005 60; /* Light background for inputs in light theme */
    --ring: 0.65 0.2 40; /* Strengthened to match accent */
    --chart-1: 0.65 0.2 40; /* Strengthened to match accent */
    --chart-2: 0.6 0.15 220;
    --chart-3: 0.65 0.18 140;
    --chart-4: 0.55 0.2 280;
    --chart-5: 0.7 0.16 60;

    /* Enhanced High-Contrast Neumorphic Light Mode Shadows with Improved Depth */
    --neomorph-shadow-sm: 3px 3px 8px rgba(0, 0, 0, 0.18), -3px -3px 8px
      rgba(255, 255, 255, 0.95);
    --neomorph-shadow: 5px 5px 14px rgba(0, 0, 0, 0.22), -5px -5px 14px
      rgba(255, 255, 255, 0.95);
    --neomorph-shadow-lg: 8px 8px 18px rgba(0, 0, 0, 0.25), -8px -8px 18px
      rgba(255, 255, 255, 0.98);
    --neomorph-shadow-xl: 10px 10px 22px rgba(0, 0, 0, 0.2), -10px -10px 22px
      rgba(255, 255, 255, 1);
    --neomorph-inset: inset 4px 4px 9px rgba(0, 0, 0, 0.16), inset -4px -4px 9px
      rgba(255, 255, 255, 0.85);
    --neomorph-inset-sm: inset 3px 3px 7px rgba(0, 0, 0, 0.14), inset -3px -3px
      7px rgba(255, 255, 255, 0.75);
    --neomorph-hover: 6px 6px 14px rgba(0, 0, 0, 0.18), -6px -6px 14px
      rgba(255, 255, 255, 0.98);
    --neomorph-pressed: inset 3px 3px 7px rgba(0, 0, 0, 0.18), inset -3px -3px
      7px rgba(255, 255, 255, 0.8);

    /* Enhanced High-Contrast Template Card Glass Effect with Better Depth */
    --template-card-shadow:
      inset 2px 2px 5px rgba(255, 255, 255, 0.6),
      inset -2px -2px 5px rgba(0, 0, 0, 0.12),
      4px 4px 10px rgba(0, 0, 0, 0.15),
      -4px -4px 10px rgba(255, 255, 255, 0.9);
    --template-card-hover-shadow:
      inset 2px 2px 5px rgba(255, 255, 255, 0.7),
      inset -2px -2px 5px rgba(0, 0, 0, 0.14),
      5px 5px 12px rgba(0, 0, 0, 0.17),
      -5px -5px 12px rgba(255, 255, 255, 0.95);

    /* Subtle orange accent ring for light theme cards */
    --neomorph-accent-ring: 0 0 0 1px rgba(var(--accent-rgb), 0.25);

    /* ════════════════════════════════════════════════════════════════════════
       FASE 1 STATS — Monthly Calendar + Goal ring + Week bars + Insight card
       Additive tokens (light theme). Mirror the .wq-ring-well engraved pattern
       but tuned for light mode: lighter inset shadows so the tiles read as
       sculpted recesses on a light surface. Orange glow uses --accent-rgb
       (232,99,10) which is theme-agnostic. Today's tile uses a ring (not a
       glow) so it stays distinct from trained days.
       ════════════════════════════════════════════════════════════════════════ */
    /* Engraved calendar day tile — square/rounded-lg variant of .wq-ring-well.
       5px inset (light-tuned) + 1px hairline rim = sculpted recess for day
        numbers. Same depth language as the weekly challenge ring well. */
    --mw-tile-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Orange glow for trained days — soft warm halo using --accent-rgb. Tuned
       for light bg: slightly lower alpha so it doesn't blow out on light. */
    --mw-tile-trained-glow: 0 0 6px rgba(var(--accent-rgb), 0.4), 0 0 12px
      rgba(var(--accent-rgb), 0.18);
    /* Ring for today's tile — thin accent outline (not a glow) so today reads
       distinct from trained days. */
    --mw-tile-today-ring: 0 0 0 1.5px rgba(var(--accent-rgb), 0.6);
    /* Subtle inset for rest days (non-trained in-month days) — lighter than
       --mw-tile-well so rest days read as quieter empty engraved tiles. */
    --mw-tile-rest: inset 3px 3px 6px rgba(0, 0, 0, 0.12), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);
    /* Monthly goal ring well — mirrors .wq-ring-well (100px, 5px inset) but
       light-tuned. Hosts ProgressRing size=88 strokeWidth=8. */
    --mw-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Orange arc glow for the monthly goal ring — same halo as .wq-arc-glow
       but light-tuned alpha. */
    --mw-ring-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);

    /* Starter plan accent colors — light-theme-optimized: slightly darker chroma
       so the thin strips and icon squares stay visible on a light background.
       Mirrors the .dark definitions (regels 122-132) but tuned for light mode. */
    --plan-orange: 0.55 0.19 45;
    --plan-blue: 0.5 0.16 240;
    --plan-green: 0.5 0.16 145;
    --plan-purple: 0.48 0.17 290;

    /* Plan accent color utilities — light-theme variants */
    --plan-chest-push: 0.55 0.19 45; /* Orange */
    --plan-back-pull: 0.5 0.16 240; /* Blue */
    --plan-legs-core: 0.5 0.16 145; /* Green */
    --plan-shoulders-arms: 0.48 0.17 290; /* Purple */

    /* ════════════════════════════════════════════════════════════════════════
       FASE 3 STATS — Fatigue vs Fitness + Push/Pull/Legs donut + Overload nav
       Additive tokens (light theme). Fitness = blauw (--chart-2 family),
       Vermoeidheid = rood (new --ff-fatigue). TSB alert = groen/oranje/rood.
       PPL donut = oranje/blauw/groen (--chart-1/2/3). Reuses --accent-hex /
       --accent-rgb for orange. Engraved wells mirror --wq-ring-well /
       --mw-ring-well pattern (light-tuned insets).
       ════════════════════════════════════════════════════════════════════════ */
    /* Fitness (blauw) — rgb triplet for gradient/glow usage in SVG + CSS.
       Matches --chart-2 light value (0.6 0.15 220). */
    --ff-fitness-rgb: 64, 140, 220;
    /* Vermoeidheid (rood) — distinct from --destructive; a fatigue red tuned
       for chart lines + KPI accent on light bg. */
    --ff-fatigue-rgb: 220, 80, 70;
    /* KPI inset well — engraved recess for the Fitness/Vermoeidheid value
       cards. Light-tuned (lighter insets than dark). Mirrors --mw-ring-well
       language but rectangular (rounded-xl). */
    --ff-kpi-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* TSB alert colors — groen (fresh) / oranje (moderate) / rood (overtrained).
       Light-tuned OKLCH values for sufficient contrast on light bg. */
    --ff-alert-green: 0.6 0.16 145;
    --ff-alert-green-rgb: 80, 180, 110;
    --ff-alert-amber: 0.7 0.17 60;
    --ff-alert-amber-rgb: 210, 145, 50;
    --ff-alert-red: 0.55 0.2 25;
    --ff-alert-red-rgb: 200, 70, 60;
    /* PPL donut ring well — mirrors --wq-ring-well / --mw-ring-well (light
       tuned). 100px+ circular recess hosting the donut SVG. */
    --ppl-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* PPL arc glow — soft drop-shadow halo on the donut arcs. Reads the
       per-arc color via --ppl-arc-rgb set on each arc element. */
    --ppl-arc-glow: 0 0 6px rgba(var(--ppl-arc-rgb, var(--accent-rgb)), 0.45), 0
      0 14px rgba(var(--ppl-arc-rgb, var(--accent-rgb)), 0.2);
    /* Overload nav-card sparkline preview area — inset well hosting the mini
       sparkline SVG so it reads as a sculpted recess, not a flat sticker. */
    --ol-nav-spark: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);

    /* ════════════════════════════════════════════════════════════════════════
       OVERLOAD PROGRESSION DETAIL PAGE — engraved KPI wells + pill selectors
       Additive tokens (light theme). Mirror the FASE 3 engraved well pattern
       (--wq-ring-well / --ff-kpi-well / --ppl-ring-well: 5px deep inset +
       hairline rim) so the Overload page shares the same sculpted-recess
       language as the rest of the Stats tab. Orange accent (#E8630A /
       --accent-rgb) is theme-agnostic. Light-tuned insets (lighter than dark)
       so the wells read as sculpted recesses on the light FAF9F7 surface.
       ════════════════════════════════════════════════════════════════════════ */
    /* KPI inset well — engraved recess for the Overload page KPI cards
       (Average Load, Total Load). Light-tuned mirror of --ff-kpi-well /
       --wq-ring-well (5px deep inset + hairline rim). */
    --op-kpi-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Chart container well — larger engraved recess hosting the Overload
       curve SVG so the chart reads as sunk into the page surface. Same depth
       language as --op-kpi-well (light-tuned 5px inset + hairline rim). */
    --op-chart-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Hero KPI well — deeper engraved recess for the hero KPI card (larger
       6px inset) so the trend value reads as the most prominent sculpted
       element on the page. Light-tuned. */
    --op-hero-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Trend arrow accent glow — soft warm halo on the hero trend arrow
       (uses --accent-rgb). Light-tuned alpha so it doesn't blow out on
       FAF9F7. */
    --op-trend-glow: 0 0 6px rgba(var(--accent-rgb), 0.4), 0 0 14px
      rgba(var(--accent-rgb), 0.18);
    /* Pill raised shadow — subtle neumorphic raised surface for inactive
       time-filter + exercise selector pills. Light-tuned (lighter than dark). */
    --op-pill-raised: 3px 3px 6px rgba(0, 0, 0, 0.14), -3px -3px 6px
      rgba(255, 255, 255, 0.85);
    /* Pill active glow — soft warm halo on the active pill (uses --accent-rgb).
       Light-tuned alpha. */
    --op-pill-active-glow: 0 0 6px rgba(var(--accent-rgb), 0.4), 0 0 14px
      rgba(var(--accent-rgb), 0.18);
    /* Empty-state container well — subtle inset for the compact empty-state
       variant. Lighter than --op-kpi-well so it reads as a quiet recess. */
    --op-empty-well: inset 3px 3px 7px rgba(0, 0, 0, 0.12), inset -3px -3px 7px
      rgba(255, 255, 255, 0.65);
    /* PR star glow — soft warm halo on PR star markers in the chart (uses
       --accent-rgb). Light-tuned alpha. */
    --op-star-glow: 0 0 4px rgba(var(--accent-rgb), 0.55), 0 0 10px
      rgba(var(--accent-rgb), 0.25);
    /* Fase 1 — Buddy Tab Challenges. Outer card engraved well (6px deeper,
       mirrors --op-hero-well light values). */
    --wvc-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18), inset -6px -6px 11px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Split-view sub-kaartje engraved well (5px, mirrors --wq-ring-well light). */
    --wvc-sub-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Comparison bar track engraved well (5px, mirrors --wq-ring-well light). */
    --wvc-bar-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* LIVE pill orange glow (uses --accent-rgb). */
    --wvc-live-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    /* Winning sub-kaartje stronger orange glow (uses --accent-rgb). */
    --wvc-winner-glow: 0 0 18px rgba(var(--accent-rgb), 0.55);
    /* Leaderboard segmented control track (5px, mirrors --wq-ring-well light). */
    --lb-seg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Leaderboard row engraved well (5px, mirrors --wq-ring-well light). */
    --lb-row-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* #1 leaderboard row stronger orange glow (uses --accent-rgb). */
    --lb-rank1-glow: 0 0 20px rgba(var(--accent-rgb), 0.6);
    /* Group average comparison card engraved well (5px, mirrors --wq-ring-well
       light). */
    --lb-avg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* PR Ladder outer card engraved well (6px deeper, mirrors --wvc-card-well
       light). */
    --pr-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18), inset -6px -6px 11px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* PR Ladder segmented control track (5px, mirrors --lb-seg-well light). */
    --pr-seg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* PR Ladder row engraved well (5px, mirrors --lb-row-well light). */
    --pr-row-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* #1 PR Ladder row stronger orange glow (uses --accent-rgb). */
    --pr-rank1-glow: 0 0 20px rgba(var(--accent-rgb), 0.6);
    /* #2 PR Ladder row softer orange glow (uses --accent-rgb). */
    --pr-rank2-glow: 0 0 14px rgba(var(--accent-rgb), 0.4);
    /* #3 PR Ladder row subtle orange glow (uses --accent-rgb). */
    --pr-rank3-glow: 0 0 10px rgba(var(--accent-rgb), 0.3);
    /* PR Ladder trophy warm orange glow (uses --accent-rgb). */
    --pr-trophy-glow: 0 0 16px rgba(var(--accent-rgb), 0.55);
    /* Fase 3 — Your Streak outer card engraved well (6px deeper, mirrors
       --wvc-card-well / --pr-card-well light). */
    --streak-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18), inset -6px -6px 11px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Streak day-circle engraved well (5px, mirrors --wq-ring-well light). */
    --streak-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Streak counter + trained day orange glow (uses --accent-rgb, mirrors
       --wvc-live-glow). */
    --streak-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    /* Fase 3 — Muscle Balance Race outer card engraved well (6px deeper,
       mirrors --wvc-card-well / --pr-card-well light). */
    --mbr-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18), inset -6px -6px 11px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Muscle Balance progress bar track engraved well (5px, mirrors
       --wvc-bar-well light). */
    --mbr-bar-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Muscle Balance Week/All-time segmented control track (5px, mirrors
       --lb-seg-well / --pr-seg-well light). */
    --mbr-seg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Muscle Balance YOU/BUDDY sub-section engraved well (5px, mirrors
       --wvc-sub-well light). */
    --mbr-sub-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16), inset -5px -5px 9px
      rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Winning PPL category stronger orange glow (uses --accent-rgb, mirrors
       --wvc-winner-glow). */
    --mbr-winner-glow: 0 0 18px rgba(var(--accent-rgb), 0.55);
    /* Ideal ratio dashed reference line color at 33% (muted). */
    --mbr-ideal-line: rgba(0, 0, 0, 0.18);

    /* ════════════════════════════════════════════════════════════════════════
       FASE 1 — BUDDY HUB OWN PLAYER CARD (closed + detail view)
       Additive tokens (light theme). The OwnPlayerCard is restyled from a flat
       mint-green card to a neumorphic engraved card with orange accent
       (#E8630A / --accent-rgb). Closed state: engraved card surface, orange-
       glow avatar ring, orange-gradient level medal with lightning icon,
       engraved XP bar track with orange glowing fill, 3 engraved stat pills
       (dumbbell/flame/star). Open state: detail view with 6-axis spider chart
       in engraved container, PPL donut in engraved well, 5 key-stat cells, and
       a rule-based insight card (30-workout threshold). All wells mirror the
       --wq-ring-well / --op-hero-well / --op-chart-well lineage (5px deep inset
       + hairline rim for wells, 6px deeper for the outer card). All glows use
       --accent-rgb (232,99,10) — theme-agnostic. Light-tuned insets.
       ════════════════════════════════════════════════════════════════════════ */
    /* Outer card engraved well — 6px deeper, mirrors --op-hero-well light.
       Hosts the whole closed card surface as a sculpted recess. */
    --op-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* XP bar track engraved well — 5px inset, mirrors --wq-ring-well light.
       Hosts the orange XP fill so the bar reads as a sunk-in track. */
    --op-xp-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Stat pill engraved well — 5px inset, mirrors --wq-ring-well light.
       Hosts the 3 stat values (volume / streak / level) as sculpted pills. */
    --op-stat-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Detail view chart container engraved well — 5px inset, mirrors
       --op-chart-well light. Hosts the spider chart + PPL donut + key-stat
       cells in the open detail view. */
    --op-detail-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Orange XP fill glow — soft warm halo on the XP bar fill (uses
       --accent-rgb). Light-tuned alpha so it doesn't blow out on FAF9F7. */
    --op-xp-glow: 0 0 6px rgba(var(--accent-rgb), 0.4), 0 0 14px
      rgba(var(--accent-rgb), 0.18);
    /* Avatar ring orange glow — soft warm halo on the avatar ring (uses
       --accent-rgb). Light-tuned alpha. */
    --op-avatar-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* Level medal orange glow — soft warm halo on the orange-gradient medal
       (uses --accent-rgb). Light-tuned alpha. */
    --op-medal-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* Spider chart fill orange glow — soft warm halo on the radar fill area
        (uses --accent-rgb). Light-tuned alpha so it doesn't blow out on FAF9F7. */
    --op-spider-glow: 0 0 6px rgba(var(--accent-rgb), 0.4), 0 0 14px
      rgba(var(--accent-rgb), 0.18);

    /* ════════════════════════════════════════════════════════════════════════
       YOUR STATS REFINEMENT — OwnPlayerCardDetail 7-point upgrade
       Additive tokens (light theme). Formalizes consistent neumorphic depth
       for the Your Stats page: stat cells / donut / radar share the SAME 5px
       deep inset + hairline rim language (mirror --op-detail-well). Toggle
       pills use raised neumorph (--op-pill-raised already exists). New tokens
       cover: hero metric typography, secondary stat typography, PPL donut 0%
       grey fill + legend colors, radar axis numeric value display, and the
       orange accent border for the coaching section connection.
       ════════════════════════════════════════════════════════════════════════ */
    /* Stat cell well — 5px deep inset, mirrors --op-detail-well light exactly.
       Same depth language for ALL stat cells (hero + secondary) + donut +
       radar so neumorphic depth reads consistently across the page. */
    --op-stat-cell-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Radar container well — 5px deep inset, mirrors --op-stat-cell-well.
       Hosts the 6-axis spider chart so the radar reads as sunk into the
       page surface at the same depth as the stat cells and donut. */
    --op-radar-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Hero metric typography — large prominent number for the hero stat
       (Total Workouts). Space Grotesk, ~3rem, bold, accent color. */
    --op-hero-metric-size: 3rem;
    --op-hero-metric-line: 1.05;
    --op-hero-metric-weight: 700;
    --op-hero-metric-tracking: -0.02em;
    /* Secondary stat typography — compact number for the 4 secondary stats.
       Space Grotesk, ~1.25rem, semibold, foreground. Visually quieter than
       the hero via smaller size + foreground (not accent) color. */
    --op-stat-secondary-size: 1.25rem;
    --op-stat-secondary-line: 1.2;
    --op-stat-secondary-weight: 600;
    /* Stat label typography — tiny uppercase muted label above each stat
       value (hero + secondary share this label style). */
    --op-stat-label-size: 0.625rem;
    --op-stat-label-tracking: 0.08em;
    --op-stat-label-weight: 600;
    /* PPL donut 0% grey fill — flat muted fill for empty/0% slices so they
       render as a visible quiet arc, NOT a thin sliver. Distinct from the
       3 colored arcs (push/pull/legs). */
    --ppl-empty-fill: rgba(0, 0, 0, 0.12);
    /* PPL legend colors — formalized rgb triplets for the 3 PPL categories.
       Push = orange (accent), Pull = blue (buddy/fitness blue), Legs = green
       (alert green). Used for arc fills + legend dots + percentage labels. */
    --ppl-push-rgb: 232, 99, 10;
    --ppl-pull-rgb: 64, 140, 220;
    --ppl-legs-rgb: 120, 200, 140;
    /* Radar axis numeric value — smaller muted number displayed next to each
       axis NAME (e.g. "Volume 84"). Reads as supporting context, not primary. */
    --op-radar-axis-value-size: 0.5625rem;
    --op-radar-axis-value-weight: 500;
    /* Coaching accent border — thin orange ring + soft outer glow that
       visually connects the coaching section as the page's insight
       conclusion. Uses --accent-rgb (theme-agnostic). */
    --op-coaching-ring: 0 0 0 1.5px rgba(var(--accent-rgb), 0.55);
    --op-coaching-glow: 0 0 12px rgba(var(--accent-rgb), 0.18), 0 0 24px
      rgba(var(--accent-rgb), 0.08);

    /* ════════════════════════════════════════════════════════════════════════
        FASE 2 — BUDDY HUB VS-COMPARISON SHEET
       Additive tokens (light theme). Formalizes the buddy-blue contrast color
       (RGB 0,146,189 — already used as PPL_RGB.pull) as a first-class CSS
       custom property so the VS spider chart, PPL donuts, and key-stats can
       reference it consistently in both dark and light themes. VS-sheet
       specific wells + glows mirror the Fase 1 OwnPlayerCard lineage
       (--op-card-well 6px deep for the sheet, --wq-ring-well 5px for stat
       rows). All glows use either --accent-rgb (orange, user side / winner)
       or --buddy-rgb (blue, buddy side). Light-tuned insets.
       ════════════════════════════════════════════════════════════════════════ */
    /* Buddy-blue contrast color — formalized from PPL_RGB.pull (0,146,189).
       Strongest contrast vs orange #E8630A. --buddy-rgb for rgba()/glow
       usage, --buddy-hex for solid fills. Theme-agnostic. */
    --buddy-rgb: 0, 146, 189;
    --buddy-hex: #0092bd;
    /* VS sheet background well — 6px deep engraved well, mirrors --op-card-well
       light. Hosts the whole VS sheet surface as a sculpted recess. */
    --vs-sheet-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* VS spider buddy glow — soft blue halo on the buddy radar polygon (uses
       --buddy-rgb). Light-tuned alpha so it doesn't blow out on FAF9F7. */
    --vs-spider-glow-buddy: 0 0 6px rgba(var(--buddy-rgb), 0.4), 0 0 14px
      rgba(var(--buddy-rgb), 0.18);
    /* VS stat winner glow — soft orange halo on the winning stat/category
       (uses --accent-rgb). Light-tuned alpha. */
    --vs-stat-winner-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* VS stat row well — 5px engraved well, mirrors --wq-ring-well light.
       Hosts each key-stat row as a sculpted recess. */
    --vs-stat-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);

    --blueprint-exercises-well:
      inset 4px 4px 8px rgba(0, 0, 0, 0.18), inset -4px -4px 8px rgba(
        255,
        255,
        255,
        0.65
      ), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Profile card neumorphic shadow + gradient end — theme-aware so the
       hardcoded rgba(18,18,18,0) gradient end and rgba(255,255,255,0.04)
       highlight adapt to light/dark. Light theme: deeper dark shadow + bright
       white highlight. Gradient end fades to transparent background. */
    --profile-card-shadow: 6px 6px 16px rgba(0, 0, 0, 0.45), -3px -3px 10px
      rgba(255, 255, 255, 0.04), 0 0 0 1px rgba(var(--accent-rgb), 0.12);
    --profile-hero-shadow: 8px 8px 20px rgba(0, 0, 0, 0.5), -4px -4px 12px
      rgba(255, 255, 255, 0.04), 0 0 0 1px rgba(var(--accent-rgb), 0.15);
    --profile-gradient-end: oklch(var(--background) / 0);
    --font-display: "Space Grotesk", sans-serif;
    --font-body: "General Sans", sans-serif;
    --font-mono: "JetBrains Mono", monospace;

    /* ════════════════════════════════════════════════════════════════════════
       MACROS — Nutrition dashboard (macro progress rings + meal sections +
       food library + nutrition streak + nutrition day-dots). Additive tokens
       (light theme). Mirrors the engraved-well lineage (--wq-ring-well /
       --op-card-well). Macro arcs read a per-macro --mn-*-rgb so each ring
       glows in its own color. Light-tuned insets.
       ════════════════════════════════════════════════════════════════════════ */
    /* Outer nutrition card well — 6px deeper, mirrors --op-card-well light.
       Hosts the whole Macros page surface as a sculpted recess. */
    --mn-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Macro progress ring well — 5px engraved inset, mirrors --wq-ring-well
       light. Hosts the circular ProgressRing for calories + per-macro rings. */
    --mn-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Meal section well — 5px engraved inset, mirrors --mn-ring-well light.
       Hosts each meal section (ontbijt/lunch/diner/snack) as a sculpted card. */
    --mn-meal-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Food item row well — 4px engraved inset, mirrors --op-empty-well light.
       Hosts each logged food / library food row as a quieter recess. */
    --mn-item-well:
      inset 4px 4px 8px rgba(0, 0, 0, 0.15),
      inset -4px -4px 8px rgba(255, 255, 255, 0.65),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Segmented control track well — 5px engraved inset, mirrors --lb-seg-well
       light. Hosts the meal/day + library/quick-add segmented controls. */
    --mn-seg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Nutrition day-dot well — 3px engraved inset, mirrors --mw-tile-rest
       light. Hosts each nutrition day-dot on the home page + weekly view. */
    --mn-dot-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);
    /* Macro arc glow — soft drop-shadow halo on the macro rings. Reads the
       per-macro --mn-arc-rgb set on each arc element (falls back to accent). */
    --mn-arc-glow: 0 0 6px rgba(var(--mn-arc-rgb, var(--accent-rgb)), 0.45), 0 0
      14px rgba(var(--mn-arc-rgb, var(--accent-rgb)), 0.2);
    /* Nutrition day-dot glow — soft warm halo on logged nutrition day-dots
       (uses --accent-rgb). */
    --mn-dot-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* Macro color triplets — theme-agnostic rgb triplets for SVG arcs + glow.
       Calories = accent orange, Protein = blue, Carbs = green, Fat = amber.
       Mirrors the PPL donut color language (orange/blue/green) + a warm amber
       for the 4th macro so all four rings stay distinct on dark stone. */
    --mn-cal-rgb: 232, 99, 10;
    --mn-protein-rgb: 64, 140, 220;
    --mn-carbs-rgb: 120, 200, 140;
    --mn-fat-rgb: 210, 170, 70;
    /* Over-goal red — distinct from --destructive; a softer red for "over
       goal" macro/calorie states (tuned for light bg). */
    --mn-over-rgb: 220, 80, 70;

    /* ════════════════════════════════════════════════════════════════════════
       FASE 2 — UNIFIED PR-LADDER CHALLENGE MODEL + LIFECYCLE STATUS
       Additive tokens (light theme). Consolidates PR-duel / PR Hunt Duo /
       PR-ladder into ONE PR-ladder challenge card and Balance Pact into one
       challenge type (metriek = push/pull/legs-balans). The lifecycle becomes
       voorgesteld → geaccepteerd → actief → afgerond → afgewikkeld with
       automatic settlement + rematch. Wells mirror the Fase 1 buddy lineage
       (--pr-card-well 6px deep for the card, --wq-ring-well 5px for sub-rows /
       metric cells). Status badges read per-state --lc-*-rgb so each lifecycle
       step gets its own color. Rematch button uses the accent gradient +
       breathing glow. All glows use --accent-rgb (orange) or --buddy-rgb
       (blue, opponent side). Light-tuned insets.
       ════════════════════════════════════════════════════════════════════════ */
    /* Unified PR-ladder card outer well — 6px deep, mirrors --pr-card-well
       light. Hosts the consolidated challenge card surface. */
    --ch-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Metric cell well — 5px engraved inset, mirrors --wq-ring-well light.
       Hosts metriek / tijdsvenster / winvoorwaarde readouts as sculpted cells. */
    --ch-metric-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Opponent (buddy) sub-row well — 5px engraved inset, mirrors --wvc-sub-well
       light. Hosts the buddy side of the ladder/balance comparison. */
    --ch-sub-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Progress bar track well — 5px engraved inset, mirrors --wvc-bar-well
       light. Hosts the win-condition progress fill. */
    --ch-bar-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Active challenge orange glow — soft warm halo (uses --accent-rgb),
       mirrors --wvc-live-glow. */
    --ch-active-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    /* Winner side stronger orange glow (uses --accent-rgb, mirrors
       --wvc-winner-glow). */
    --ch-winner-glow: 0 0 18px rgba(var(--accent-rgb), 0.55);
    /* Opponent (buddy) side blue glow (uses --buddy-rgb, mirrors
       --vs-spider-glow-buddy). */
    --ch-buddy-glow: 0 0 6px rgba(var(--buddy-rgb), 0.45), 0 0 14px
      rgba(var(--buddy-rgb), 0.2);
    /* Rematch button breathing glow — accent gradient button halo (uses
       --accent-rgb, mirrors --op-pill-active-glow). */
    --ch-rematch-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* Lifecycle status badge rgb triplets — theme-agnostic. Each lifecycle
       step gets its own color so the status reads at a glance:
       voorgesteld = muted stone, geaccepteerd = buddy-blue, actief = orange,
       afgerond = green, afgewikkeld = neutral/foreground. */
    --lc-proposed-rgb: 140, 140, 140;
    --lc-accepted-rgb: 0, 146, 189;
    --lc-active-rgb: 232, 99, 10;
    --lc-done-rgb: 120, 200, 140;
    --lc-settled-rgb: 200, 200, 200;
    /* Lifecycle status badge well — 3px engraved inset, mirrors --mw-tile-rest
       light. Hosts the status pill so it reads as a quiet sculpted chip. */
    --lc-badge-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);

    /* ════════════════════════════════════════════════════════════════════════
       FASE 3 — CHALLENGECENTRUM (status groups + filter + countdown + actions)
       Additive tokens (light theme). One Challengecentrum section replaces the
       old ChallengeHub / Pending / Active sections with three status groups:
       Voorgesteld (muted stone), Actief (orange glow), Afgerond (green). Status
       colors reuse the Fase 2 lifecycle rgb triplets (--lc-proposed-rgb /
       --lc-active-rgb / --lc-done-rgb) and --accent-rgb / --buddy-rgb. Group
       containers mirror the --ch-card-well engraved lineage; filter + countdown
       mirror the segmented-control / badge-well lineage. Light-tuned insets.
       ════════════════════════════════════════════════════════════════════════ */
    /* Status group accent rgb triplets — theme-agnostic, alias the Fase 2
       lifecycle colors so each status group reads at a glance. */
    --cc-proposed-rgb: 140, 140, 140;
    --cc-active-rgb: 232, 99, 10;
    --cc-done-rgb: 120, 200, 140;
    /* Status group glows — soft halo on the group container + dot (uses the
       per-group --cc-*-rgb). Light-tuned alpha. */
    --cc-proposed-glow: 0 0 8px rgba(var(--cc-proposed-rgb), 0.3);
    --cc-active-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    --cc-done-glow: 0 0 12px rgba(var(--cc-done-rgb), 0.4);
    /* Status group container well — 6px deep engraved recess, mirrors
       --ch-card-well light. Hosts each status group surface. */
    --cc-group-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Challenge card well — 5px engraved recess, mirrors --ch-metric-well
       light. Hosts each individual challenge card inside a group. */
    --cc-card-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Status filter segmented track — 5px engraved inset, mirrors
       --lb-seg-well / --mn-seg-well light. Hosts Alle/Voorgesteld/Actief/
       Afgerond options. */
    --cc-filter-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Filter active option glow — orange halo on the selected filter option
       (uses --accent-rgb, mirrors --op-pill-active-glow light). */
    --cc-filter-active-glow: 0 0 6px rgba(var(--accent-rgb), 0.4), 0 0 14px
      rgba(var(--accent-rgb), 0.18);
    /* Countdown timer chip well — 3px engraved inset, mirrors --lc-badge-well
       light. Hosts the countdown pill. */
    --cc-countdown-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px
      6px rgba(255, 255, 255, 0.6);
    /* Countdown urgent glow — orange halo when time is running low (uses
       --accent-rgb). Light-tuned alpha. */
    --cc-countdown-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* Action button glows — accept = orange, decline = muted red, settle =
       buddy-blue. Rematch reuses --ch-rematch-glow (already defined). */
    --cc-accept-glow: 0 0 6px rgba(var(--accent-rgb), 0.5), 0 0 14px
      rgba(var(--accent-rgb), 0.25);
    --cc-decline-rgb: 200, 80, 70;
    --cc-decline-glow: 0 0 6px rgba(var(--cc-decline-rgb), 0.4);
    --cc-settle-glow: 0 0 6px rgba(var(--buddy-rgb), 0.45), 0 0 14px
      rgba(var(--buddy-rgb), 0.2);
    /* Disabled action state — muted text + reduced opacity so unavailable
       lifecycle actions read as inert. */
    --cc-disabled-rgb: 130, 130, 130;
    --cc-disabled-opacity: 0.45;

    /* ════════════════════════════════════════════════════════════════════════
       FASE 4 — BUDDY RANKING + VERANTWOORDING (accountability) + SHOWDOWN
       Additive tokens (light theme). Reuse the engraved-well lineage with new
       prefixes: --rk-* (ranking wells), --ac-* (accountability chips),
       --sd-* (showdown ceremony). Orange accent (--accent-rgb) marks the own
       player / winner / active state; buddy-blue (--buddy-rgb) marks the
       opponent / bond. Light-tuned insets (mirror the :root cc/ch wells).
       ════════════════════════════════════════════════════════════════════════ */
    /* Ranking outer card well — 6px deep engraved well, mirrors --ch-card-well
       light. Hosts the whole ranking surface as a sculpted recess. */
    --rk-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Ranking row well — 5px engraved well, mirrors --lb-row-well light.
       Hosts each ranked player row. */
    --rk-row-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Own player row orange glow — highlights the own player (uses
       --accent-rgb, mirrors --ch-active-glow light). */
    --rk-self-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    /* #1 row stronger orange glow (uses --accent-rgb, mirrors --lb-rank1-glow). */
    --rk-top-glow: 0 0 20px rgba(var(--accent-rgb), 0.6);
    /* Buddy position blue glow — marks the buddy's row in the ranking (uses
       --buddy-rgb, mirrors --ch-buddy-glow light). */
    --rk-pos-glow: 0 0 6px rgba(var(--buddy-rgb), 0.45), 0 0 14px
      rgba(var(--buddy-rgb), 0.2);
    /* Points breakdown cell well — 5px engraved well, mirrors --ch-metric-well
       light. Hosts the per-player points split (challenge/showdown/streaks). */
    --rk-point-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Ranking period chip well — 3px engraved inset, mirrors --lc-badge-well
       light. Hosts the current ranking period + visible start date. */
    --rk-period-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);
    /* Accountability metric chip well — 3px engraved inset, mirrors
       --lc-badge-well light. Hosts streak / buddy bond / consistency chips. */
    --ac-chip-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);
    /* Streak metric orange glow (uses --accent-rgb). */
    --ac-streak-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* Buddy bond metric blue glow (uses --buddy-rgb). */
    --ac-bond-glow: 0 0 6px rgba(var(--buddy-rgb), 0.45), 0 0 14px
      rgba(var(--buddy-rgb), 0.2);
    /* Consistency metric green rgb triplet — mirrors --ff-alert-green-rgb. */
    --ac-consistency-rgb: 120, 200, 140;
    /* Showdown card well — 6px deep engraved well, mirrors --ch-card-well
       light. Hosts the showdown event surface. */
    --sd-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Ceremony stage well — 5px engraved well, mirrors --wq-ring-well light.
       Hosts the showdown result ceremony stage. */
    --sd-stage-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Showdown winner orange glow (uses --accent-rgb, mirrors --ch-winner-glow
       light). */
    --sd-winner-glow: 0 0 18px rgba(var(--accent-rgb), 0.55);
    /* Showdown opponent blue glow (uses --buddy-rgb, mirrors --ch-buddy-glow). */
    --sd-buddy-glow: 0 0 6px rgba(var(--buddy-rgb), 0.45), 0 0 14px
      rgba(var(--buddy-rgb), 0.2);
    /* Ceremony confetti rgb triplet — orange (uses --accent-rgb). */
    --sd-confetti-rgb: 232, 99, 10;
    /* Ceremony trophy orange glow (mirrors --pr-trophy-glow light). */
    --sd-trophy-glow: 0 0 16px rgba(var(--accent-rgb), 0.55);

    /* ════════════════════════════════════════════════════════════════════════
       FASE 5 — GEDEELD PLAN (shared training plan)
       Additive tokens (light theme). Reuse the engraved-well lineage with the
       --sp-* prefix. --sp-card-well mirrors the --ch-card-well light raised
       card; --sp-day-well / --sp-goal-well / --sp-track-well mirror the
       --cc-card-well / --cc-filter-well engraved recesses; --sp-chip-self /
       --sp-chip-buddy glows use --accent-rgb (orange, self) and --buddy-rgb
       (blue, buddy). Light-tuned insets.
       ════════════════════════════════════════════════════════════════════════ */
    /* Shared plan outer card well — 6px deep engraved recess, mirrors
       --ch-card-well light. Hosts the whole shared plan surface. */
    --sp-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Shared training day row well — 5px engraved recess, mirrors
       --cc-card-well light. Hosts each shared training day. */
    --sp-day-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Joint goal cell well — 5px engraved inset, mirrors --cc-filter-well
       light. Hosts each editable joint-goal input. */
    --sp-goal-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Joint progress track well — 5px engraved inset, mirrors --cc-filter-well
       light. Hosts the progress fill. */
    --sp-track-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Progress fill glow — orange halo on the joint progress fill (uses
       --accent-rgb, mirrors --cc-accept-glow light). */
    --sp-fill-glow: 0 0 6px rgba(var(--accent-rgb), 0.5), 0 0 14px
      rgba(var(--accent-rgb), 0.25);
    /* Per-buddy completion chip glows — self = orange (--accent-rgb), buddy =
       blue (--buddy-rgb). Light-tuned alpha. */
    --sp-chip-self-glow: 0 0 6px rgba(var(--accent-rgb), 0.4);
    --sp-chip-buddy-glow: 0 0 6px rgba(var(--buddy-rgb), 0.4);
    /* Empty state well — 3px engraved inset, mirrors --cc-countdown-well
       light. Hosts the helpful empty state. */
    --sp-empty-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);

    /* ════════════════════════════════════════════════════════════════════════
       BUDDY HUB IMPROVED — rich empty states + challenge tooltips/guidelines
       + dedicated player card page. Additive tokens (light theme). Follows the
       engraved-well lineage (--op-card-well 6px deep for the page card,
       --wq-ring-well 5px for wells, --op-empty-well 3px for quiet recesses).
       Empty-state icon + CTA glow use --accent-rgb (orange); tooltip uses
       --buddy-rgb (blue) for the info affordance. Light-tuned insets.
       ════════════════════════════════════════════════════════════════════════ */
    /* Rich empty-state container well — 5px engraved recess, mirrors
       --wq-ring-well light. Hosts the icon + explanation + first-action CTA. */
    --bh-empty-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Empty-state icon well — 3px engraved circular recess, mirrors
       --mw-tile-rest light. Hosts the leading icon so it reads as sunk in. */
    --bh-empty-icon-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px
      6px rgba(255, 255, 255, 0.6);
    /* Empty-state icon glow — soft orange halo on the leading icon (uses
       --accent-rgb, mirrors --op-avatar-glow light). */
    --bh-empty-icon-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* Empty-state first-action glow — orange halo on the primary CTA button
       (uses --accent-rgb, mirrors --cc-accept-glow light). */
    --bh-empty-cta-glow: 0 0 6px rgba(var(--accent-rgb), 0.5), 0 0 14px
      rgba(var(--accent-rgb), 0.25);
    /* Empty-state eyebrow chip well — 3px engraved inset, mirrors
       --lc-badge-well light. Hosts the section eyebrow label. */
    --bh-empty-eyebrow-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px
      -3px 6px rgba(255, 255, 255, 0.6);
    /* Challenge tooltip well — 3px engraved inset, mirrors --cc-countdown-well
       light. Hosts the tooltip popover surface. */
    --bh-tip-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);
    /* Challenge tooltip glow — soft blue halo on the info tooltip (uses
       --buddy-rgb, mirrors --ch-buddy-glow light). */
    --bh-tip-glow: 0 0 6px rgba(var(--buddy-rgb), 0.45), 0 0 14px
      rgba(var(--buddy-rgb), 0.2);
    /* Challenge tooltip arrow — theme-aware solid fill matching the tooltip
       surface so the pointer blends into the popover. */
    --bh-tip-arrow: oklch(var(--card));
    /* Challenge guideline card well — 5px engraved recess, mirrors
       --ch-metric-well light. Hosts the rules/richtlijnen panel. */
    --bh-guide-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Challenge guideline accent — orange left border + soft halo marking the
       rules panel (uses --accent-rgb, mirrors --op-coaching-ring light). */
    --bh-guide-ring: 0 0 0 1.5px rgba(var(--accent-rgb), 0.5);
    --bh-guide-glow: 0 0 10px rgba(var(--accent-rgb), 0.16), 0 0 20px
      rgba(var(--accent-rgb), 0.08);
    /* Dedicated player card page outer well — 6px deep engraved recess,
       mirrors --op-card-well light. Hosts the whole player card page surface. */
    --bh-page-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Player card page hero well — deeper 6px engraved recess, mirrors
       --op-hero-well light. Hosts the avatar + level medal + name header. */
    --bh-page-hero-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Player card page section well — 5px engraved recess, mirrors
       --op-detail-well light. Hosts each stat/XP/accountability section. */
    --bh-page-section-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Player card page back button glow — orange halo on the back affordance
       (uses --accent-rgb, mirrors --op-pill-active-glow light). */
    --bh-page-back-glow: 0 0 6px rgba(var(--accent-rgb), 0.4), 0 0 14px
      rgba(var(--accent-rgb), 0.18);

    /* ════════════════════════════════════════════════════════════════════════
       COMPACT PERIOD SEGMENTED CONTROL — Progression stats cards
       Additive tokens (light theme). One slim pill-shaped segmented control
       replaces the four bulky inline period selectors on the stats cards
       (Muscle Balance / OneRM / Fatigue vs Fitness / PPL Balance). Mirrors the
       --lb-seg-well / --mn-seg-well engraved-well lineage (5px deep inset +
       hairline rim) but slimmer so the control reads as a compact recessed
       track. Active period = orange accent glow (--op-pill-active-glow style)
       + accent text; inactive = muted raised. Collapses to a small dropdown on
       narrow phones via a @media query (see .period-seg in @layer components).
       ════════════════════════════════════════════════════════════════════════ */
    /* Segmented track well — slimmer engraved recess hosting the period
       options. Light-tuned (lighter insets than dark, mirrors --lb-seg-well /
       --mn-seg-well light values). */
    --ps-seg-well:
      inset 4px 4px 7px rgba(0, 0, 0, 0.14),
      inset -4px -4px 7px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Raised button shadow — subtle neumorphic raised surface for each period
       button (inactive). Mirrors --op-pill-raised light. */
    --ps-btn-raised: 2px 2px 4px rgba(0, 0, 0, 0.13), -2px -2px 4px
      rgba(255, 255, 255, 0.85);
    /* Active period glow — soft warm halo on the selected period (uses
       --accent-rgb, mirrors --op-pill-active-glow light). */
    --ps-btn-active-glow: 0 0 6px rgba(var(--accent-rgb), 0.4), 0 0 14px
      rgba(var(--accent-rgb), 0.18);
    /* Active period pressed shadow — engraved inset when the active button is
       pressed (reads as sunk into the track). */
    --ps-btn-pressed: inset 2px 2px 4px rgba(0, 0, 0, 0.16), inset -2px -2px 4px
      rgba(255, 255, 255, 0.7);

    /* ════════════════════════════════════════════════════════════════════════
       HOME WELCOME BLOCK — new-user hero (0 workouts)
       Additive tokens (light theme). A warm, polished, stable welcome hero for
       new users: the ONLY thing shown before the first completed workout (no
       stats). Mirrors the engraved-well lineage (--op-card-well 6px deep for
       the hero card, --wq-ring-well 5px for the icon well). Orange accent
       (#E8630A / --accent-rgb) reserved for the single primary CTA + leading
       icon glow. Restrained by design — stability and a clean first impression
       take priority over visual flourish.
       ════════════════════════════════════════════════════════════════════════ */
    /* Welcome hero card well — 6px deep engraved recess, mirrors --op-card-well
       light. Hosts the whole welcome block surface as a sculpted recess. */
    --wb-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Leading icon well — 5px engraved circular recess, mirrors --wq-ring-well
       light. Hosts the dumbbell/start icon so it reads as sunk in. */
    --wb-icon-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Leading icon glow — soft orange halo on the icon (uses --accent-rgb,
       mirrors --op-avatar-glow light). */
    --wb-icon-glow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
      rgba(var(--accent-rgb), 0.2);
    /* Eyebrow chip well — 3px engraved inset, mirrors --lc-badge-well light.
       Hosts the small uppercase eyebrow label above the headline. */
    --wb-eyebrow-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px
      6px rgba(255, 255, 255, 0.6);
    /* Primary CTA glow — soft orange breathing halo on the "start training"
       button (uses --accent-rgb, mirrors --cc-accept-glow light). */
    --wb-cta-glow: 0 0 6px rgba(var(--accent-rgb), 0.5), 0 0 14px
      rgba(var(--accent-rgb), 0.25);

    /* ════════════════════════════════════════════════════════════════════════
       BLUEPRINT SHARING — public shared view + share/import CTAs
       Additive tokens (light theme). Follows the engraved-well lineage
       (--op-card-well 6px deep for the page card, --wq-ring-well 5px for rows,
       --lc-badge-well 3px for chips). The PUBLIC read-only view is visually
       separated from the owner's edit view by using the buddy-blue
       (--buddy-rgb) as its distinguishing accent — orange (#E8630A) stays the
       owner/editable/primary-action color, blue marks "shared with others /
       read-only". The import + share CTAs use the orange accent. Light-tuned
       insets.
       ════════════════════════════════════════════════════════════════════════ */
    /* Public shared-view outer card well — 6px deep engraved recess, mirrors
       --op-card-well light. Hosts the whole public blueprint surface. */
    --sh-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.18),
      inset -6px -6px 11px rgba(255, 255, 255, 0.72),
      inset 0 0 0 1px rgba(0, 0, 0, 0.05);
    /* Public shared-view header band — subtle blue-tinted surface (uses
       --buddy-rgb) so the read-only view reads as a "shared showcase" distinct
       from the owner's edit view. */
    --sh-header-rgb: 0, 146, 189;
    --sh-header-glow: 0 0 6px rgba(var(--buddy-rgb), 0.35), 0 0 14px
      rgba(var(--buddy-rgb), 0.16);
    /* Public badge chip well — 3px engraved inset, mirrors --lc-badge-well
       light. Hosts the "Gedeeld plan" / "Alleen-lezen" pill. */
    --sh-badge-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px 6px
      rgba(255, 255, 255, 0.6);
    /* Read-only training day row well — 5px engraved recess, mirrors
       --cc-card-well light. Hosts each day in the public view. */
    --sh-day-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Exercise spec cell well — 4px engraved inset, mirrors --op-empty-well
       light. Hosts per-exercise specs (sets/reps/rust/cardio) in read-only. */
    --sh-spec-well:
      inset 4px 4px 8px rgba(0, 0, 0, 0.15), inset -4px -4px 8px
      rgba(255, 255, 255, 0.65), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Public eyebrow chip well — 3px engraved inset, mirrors --lc-badge-well
       light. Hosts the "Gedeeld door {naam}" label. */
    --sh-eyebrow-well: inset 3px 3px 6px rgba(0, 0, 0, 0.14), inset -3px -3px
      6px rgba(255, 255, 255, 0.6);
    /* Import CTA glow — orange breathing halo on the primary import button
       (uses --accent-rgb, mirrors --cc-accept-glow light). */
    --sh-import-glow: 0 0 6px rgba(var(--accent-rgb), 0.5), 0 0 14px
      rgba(var(--accent-rgb), 0.25);
    /* Share CTA glow — orange breathing halo on the owner's share button
       (uses --accent-rgb, mirrors --cc-accept-glow light). */
    --sh-share-glow: 0 0 6px rgba(var(--accent-rgb), 0.5), 0 0 14px
      rgba(var(--accent-rgb), 0.25);
    /* Share-link copy field well — 4px engraved inset, mirrors --mn-item-well
       light. Hosts the read-only share URL so it reads as a quiet recess. */
    --sh-link-well:
      inset 4px 4px 8px rgba(0, 0, 0, 0.15), inset -4px -4px 8px
      rgba(255, 255, 255, 0.65), inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Login-prompt banner well — 5px engraved recess, mirrors --wq-ring-well
       light. Hosts the "Log in om te importeren" hint for visitors. */
    --sh-login-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.16),
      inset -5px -5px 9px rgba(255, 255, 255, 0.7),
      inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    /* Weekly Challenge reward badge state defaults — accent-tinted so the
       "+XP" badge is accent-colored in light mode too. Mirrors the dark
       theme defaults; state 2/3 overrides still apply via .wq-card--state-*. */
    --wq-state-color: var(--accent-hex);
    --wq-state-rgb: var(--accent-rgb);
  }

  .dark {
    /* Refined Dark Mode Backgrounds with Better Contrast: #1A1A1A / #202020 */
    --background: 0.21 0 0;
    --foreground: 0.98 0 0;
    --card: 0.25 0 0;
    --card-foreground: 0.98 0 0;
    --popover: 0.29 0 0;
    --popover-foreground: 0.98 0 0;
    --primary: 0.92 0 0;
    --primary-foreground: 0.21 0 0;
    --secondary: 0.29 0 0;
    --secondary-foreground: 0.98 0 0;
    --muted: 0.33 0 0;
    --muted-foreground: 0.72 0 0;
    --accent: 0.65 0.19 40;
    --accent-foreground: 0.98 0 0;
    /* FASE 1 accent variables — central orange accent (#E8630A) and its variants.
       Mirrored from :root so dark theme uses the same accent values. */
    --accent-hex: #e8630a;
    --accent-rgb: 232, 99, 10;
    --accent-dim: #4a2400;
    --destructive: 0.577 0.245 27.325;
    --destructive-foreground: 0.98 0 0;
    --border: 0.33 0 0;
    --input: 0.33 0 0;
    --ring: 0.65 0.19 40;
    --chart-1: 0.65 0.19 40;
    --chart-2: 0.6 0.15 220;
    --chart-3: 0.65 0.18 140;
    --chart-4: 0.55 0.2 280;
    --chart-5: 0.7 0.16 60;

    /* Starter plan accent colors — used only for thin strips and icon squares */
    --plan-orange: 0.65 0.2 45;
    --plan-blue: 0.6 0.15 240;
    --plan-green: 0.65 0.18 145;
    --plan-purple: 0.58 0.18 290;

    /* Plan accent color utilities */
    --plan-chest-push: 0.65 0.2 45; /* Orange */
    --plan-back-pull: 0.6 0.15 240; /* Blue */
    --plan-legs-core: 0.65 0.18 145; /* Green */
    --plan-shoulders-arms: 0.58 0.18 290; /* Purple */

    /* Subtle Neumorphic Dark Mode Shadows — zachte diepte zonder
       heldere witte highlights. Donkere schaduw blijft aanwezig voor
       diepte, witte highlight zeer subtiel (0.03-0.05) om verhevening
       te suggereren zonder te helder/verheven te lijken. Licht thema
       (boven) blijft ongewijzigd. */
    --neomorph-shadow-sm: 3px 3px 5px rgba(0, 0, 0, 0.48), -3px -3px 5px
      rgba(255, 255, 255, 0.04);
    --neomorph-shadow: 6px 6px 10px rgba(0, 0, 0, 0.58), -6px -6px 10px
      rgba(255, 255, 255, 0.04);
    --neomorph-shadow-lg: 8px 8px 13px rgba(0, 0, 0, 0.62), -8px -8px 13px
      rgba(255, 255, 255, 0.05);
    --neomorph-shadow-xl: 11px 11px 18px rgba(0, 0, 0, 0.65), -11px -11px 18px
      rgba(255, 255, 255, 0.05);
    --neomorph-inset: inset 4px 4px 7px rgba(0, 0, 0, 0.58), inset -4px -4px 7px
      rgba(255, 255, 255, 0.04);
    --neomorph-inset-sm: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px
      5px rgba(255, 255, 255, 0.03);
    --neomorph-hover: 7px 7px 12px rgba(0, 0, 0, 0.62), -7px -7px 12px
      rgba(255, 255, 255, 0.05);
    --neomorph-pressed: inset 3px 3px 5px rgba(0, 0, 0, 0.62), inset -3px -3px
      5px rgba(255, 255, 255, 0.03);

    /* Subtle Template Card Glass Effect — minder alpha, minder spreiding */
    --template-card-shadow:
      inset 2px 2px 4px rgba(255, 255, 255, 0.04),
      inset -2px -2px 4px rgba(0, 0, 0, 0.3),
      4px 4px 8px rgba(0, 0, 0, 0.45),
      -4px -4px 8px rgba(255, 255, 255, 0.03);
    --template-card-hover-shadow:
      inset 2px 2px 4px rgba(255, 255, 255, 0.05),
      inset -2px -2px 4px rgba(0, 0, 0, 0.35),
      5px 5px 9px rgba(0, 0, 0, 0.52),
      -5px -5px 9px rgba(255, 255, 255, 0.04);

    /* No accent ring in dark theme */
    --neomorph-accent-ring: 0 0 0 transparent;

    /* ════════════════════════════════════════════════════════════════════════
       WEEKLY CHALLENGE — compacted card tokens (Phase: Compacted Weekly Challenge)
       Engraved ring well: deeper inset than --neomorph-inset-sm so the
       ProgressRing SVG appears sunk into the card surface. Soft dark inner
       shadow + subtle outer highlight = sculpted recess. The progress arc
       carries a soft warm glow tuned for near-black (no blowout).
       State colors are applied via --wq-state-color on the card root; the
       arc glow utility reads that variable so all 3 states share one rule.
       ════════════════════════════════════════════════════════════════════════ */
    --blueprint-exercises-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px rgba(
        255,
        255,
        255,
        0.05
      ), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Profile card neumorphic shadow + gradient end — dark theme mirror of the
       :root tokens. Darker alpha for the dark shadow (deeper on near-black),
       subtle white highlight (0.05) so the card still reads as raised without
       blowing out. Gradient end fades to transparent background. */
    --profile-card-shadow: 6px 6px 16px rgba(0, 0, 0, 0.68), -3px -3px 10px
      rgba(255, 255, 255, 0.05), 0 0 0 1px rgba(var(--accent-rgb), 0.18);
    --profile-hero-shadow: 8px 8px 20px rgba(0, 0, 0, 0.74), -4px -4px 12px
      rgba(255, 255, 255, 0.05), 0 0 0 1px rgba(var(--accent-rgb), 0.2);
    --profile-gradient-end: oklch(var(--background) / 0);
    --wq-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    --wq-arc-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    --wq-state-color: var(--accent-hex);
    --wq-state-rgb: var(--accent-rgb);

    /* ════════════════════════════════════════════════════════════════════════
       FASE 1 STATS — Monthly Calendar + Goal ring + Week bars + Insight card
       Additive tokens (dark theme). Mirror the .wq-ring-well engraved pattern
       exactly (5px deep inset + hairline rim) so calendar tiles and the
       monthly goal ring share the same sculpted-recess language as the weekly
       challenge ring. Orange glow uses --accent-rgb (232,99,10). Today's tile uses
       a ring (not a glow) so it stays distinct from trained days.
       ════════════════════════════════════════════════════════════════════════ */
    /* Engraved calendar day tile — square/rounded-lg variant of .wq-ring-well.
       Same 5px deep inset + 1px hairline rim = sculpted recess on near-black. */
    --mw-tile-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Orange glow for trained days — soft warm halo using --accent-rgb. Tuned
       for near-black: matches .wq-arc-glow alpha so it doesn't blow out. */
    --mw-tile-trained-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Ring for today's tile — thin accent outline (not a glow) so today reads
       distinct from trained days. */
    --mw-tile-today-ring: 0 0 0 1.5px rgba(var(--accent-rgb), 0.7);
    /* Subtle inset for rest days (non-trained in-month days) — lighter than
       --mw-tile-well so rest days read as quieter empty engraved tiles. */
    --mw-tile-rest: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px 5px
      rgba(255, 255, 255, 0.03);
    /* Monthly goal ring well — mirrors .wq-ring-well exactly (100px, 5px
       inset, hairline rim). Hosts ProgressRing size=88 strokeWidth=8. */
    --mw-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Orange arc glow for the monthly goal ring — same halo as .wq-arc-glow. */
    --mw-ring-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);

    /* ════════════════════════════════════════════════════════════════════════
       FASE 3 STATS — Fatigue vs Fitness + Push/Pull/Legs donut + Overload nav
       Additive tokens (dark theme). Mirror the :root FASE 3 tokens with dark-
       tuned insets. --ff-kpi-well and --ppl-ring-well copy the exact
       --wq-ring-well dark shadow values (5px deep inset + hairline rim) so the
       KPI cards and PPL donut share the same sculpted-recess language as the
        weekly challenge / monthly goal rings on near-black.
       ════════════════════════════════════════════════════════════════════════ */
    /* Fitness (blauw) — rgb triplet for gradient/glow usage in SVG + CSS.
       Matches --chart-2 dark value (0.6 0.15 220). */
    --ff-fitness-rgb: 64, 140, 220;
    /* Vermoeidheid (rood) — distinct from --destructive; a fatigue red tuned
       for chart lines + KPI accent on near-black. */
    --ff-fatigue-rgb: 220, 80, 70;
    /* KPI inset well — engraved recess for the Fitness/Vermoeidheid value
       cards. Copies the exact --wq-ring-well dark shadow values (5px deep
       inset + hairline rim) so KPI cards share the same sculpted language. */
    --ff-kpi-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* TSB alert colors — groen (fresh) / oranje (moderate) / rood (overtrained).
       Dark-tuned OKLCH values for sufficient contrast on near-black. */
    --ff-alert-green: 0.65 0.18 145;
    --ff-alert-green-rgb: 120, 200, 140;
    --ff-alert-amber: 0.75 0.18 60;
    --ff-alert-amber-rgb: 220, 160, 60;
    --ff-alert-red: 0.6 0.22 25;
    --ff-alert-red-rgb: 210, 90, 80;
    /* PPL donut ring well — copies the exact --wq-ring-well dark shadow values
       (5px deep inset + hairline rim). 100px+ circular recess hosting the
       donut SVG. */
    --ppl-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* PPL arc glow — soft drop-shadow halo on the donut arcs. Reads the
       per-arc color via --ppl-arc-rgb set on each arc element. */
    --ppl-arc-glow: 0 0 6px rgba(var(--ppl-arc-rgb, var(--accent-rgb)), 0.55), 0
      0 14px rgba(var(--ppl-arc-rgb, var(--accent-rgb)), 0.28);
    /* Overload nav-card sparkline preview area — inset well hosting the mini
       sparkline SVG so it reads as a sculpted recess, not a flat sticker. */
    --ol-nav-spark: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px 5px
      rgba(255, 255, 255, 0.03);

    /* ════════════════════════════════════════════════════════════════════════
       OVERLOAD PROGRESSION DETAIL PAGE — engraved KPI wells + pill selectors
       Additive tokens (dark theme). Mirror the :root Overload tokens with
       dark-tuned insets. --op-kpi-well and --op-chart-well copy the exact
       --wq-ring-well dark shadow values (5px deep inset + hairline rim) so
       the Overload page shares the same sculpted-recess language as the
        weekly challenge / monthly goal / PPL donut wells on near-black. Orange
       accent (#E8630A / --accent-rgb) is theme-agnostic.
       ════════════════════════════════════════════════════════════════════════ */
    /* KPI inset well — engraved recess for the Overload page KPI cards.
       Copies the exact --wq-ring-well dark shadow values (5px deep inset +
       hairline rim). */
    --op-kpi-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Chart container well — larger engraved recess hosting the Overload
       curve SVG. Same depth language as --op-kpi-well (copies exact
       --wq-ring-well dark shadow values). */
    --op-chart-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Hero KPI well — deeper engraved recess for the hero KPI card (larger
       6px inset) so the trend value reads as the most prominent sculpted
       element on the page. Dark-tuned (deeper than --op-kpi-well). */
    --op-hero-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.74),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.025);
    /* Trend arrow accent glow — soft warm halo on the hero trend arrow
       (uses --accent-rgb). Tuned for near-black (matches .wq-arc-glow alpha). */
    --op-trend-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Pill raised shadow — subtle neumorphic raised surface for inactive
       time-filter + exercise selector pills. Dark-tuned (subtle white
       highlight). */
    --op-pill-raised: 3px 3px 6px rgba(0, 0, 0, 0.5), -3px -3px 6px
      rgba(255, 255, 255, 0.04);
    /* Pill active glow — soft warm halo on the active pill (uses --accent-rgb).
       Tuned for near-black (matches .wq-arc-glow alpha). */
    --op-pill-active-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Empty-state container well — subtle inset for the compact empty-state
       variant. Dark-tuned (lighter than --op-kpi-well). */
    --op-empty-well: inset 3px 3px 6px rgba(0, 0, 0, 0.5), inset -3px -3px 6px
      rgba(255, 255, 255, 0.03);
    /* PR star glow — soft warm halo on PR star markers in the chart (uses
       --accent-rgb). Tuned for near-black. */
    --op-star-glow: 0 0 4px rgba(var(--accent-rgb), 0.6), 0 0 10px
      rgba(var(--accent-rgb), 0.32);
    /* Fase 1 — Buddy Tab Challenges. Outer card engraved well (6px deeper,
       mirrors --op-hero-well dark values). */
    --wvc-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.7), inset -6px -6px 11px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Split-view sub-kaartje engraved well (5px, mirrors --wq-ring-well dark). */
    --wvc-sub-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Comparison bar track engraved well (5px, mirrors --wq-ring-well dark). */
    --wvc-bar-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* LIVE pill orange glow (uses --accent-rgb). */
    --wvc-live-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    /* Winning sub-kaartje stronger orange glow (uses --accent-rgb). */
    --wvc-winner-glow: 0 0 18px rgba(var(--accent-rgb), 0.55);
    /* Leaderboard segmented control track (5px, mirrors --wq-ring-well dark). */
    --lb-seg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Leaderboard row engraved well (5px, mirrors --wq-ring-well dark). */
    --lb-row-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* #1 leaderboard row stronger orange glow (uses --accent-rgb). */
    --lb-rank1-glow: 0 0 20px rgba(var(--accent-rgb), 0.6);
    /* Group average comparison card engraved well (5px, mirrors --wq-ring-well
       dark). */
    --lb-avg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* PR Ladder outer card engraved well (6px deeper, mirrors --wvc-card-well
       dark). */
    --pr-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.68), inset -6px -6px 11px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* PR Ladder segmented control track (5px, mirrors --lb-seg-well dark). */
    --pr-seg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* PR Ladder row engraved well (5px, mirrors --lb-row-well dark). */
    --pr-row-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* #1 PR Ladder row stronger orange glow (uses --accent-rgb). */
    --pr-rank1-glow: 0 0 20px rgba(var(--accent-rgb), 0.6);
    /* #2 PR Ladder row softer orange glow (uses --accent-rgb). */
    --pr-rank2-glow: 0 0 14px rgba(var(--accent-rgb), 0.4);
    /* #3 PR Ladder row subtle orange glow (uses --accent-rgb). */
    --pr-rank3-glow: 0 0 10px rgba(var(--accent-rgb), 0.3);
    /* PR Ladder trophy warm orange glow (uses --accent-rgb). */
    --pr-trophy-glow: 0 0 16px rgba(var(--accent-rgb), 0.55);
    /* Fase 3 — Your Streak outer card engraved well (6px deeper, mirrors
       --wvc-card-well / --pr-card-well dark). */
    --streak-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.7), inset -6px -6px 11px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Streak day-circle engraved well (5px, mirrors --wq-ring-well dark). */
    --streak-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Streak counter + trained day orange glow (uses --accent-rgb, mirrors
       --wvc-live-glow). */
    --streak-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    /* Fase 3 — Muscle Balance Race outer card engraved well (6px deeper,
       mirrors --wvc-card-well / --pr-card-well dark). */
    --mbr-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.7), inset -6px -6px 11px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Muscle Balance progress bar track engraved well (5px, mirrors
       --wvc-bar-well dark). */
    --mbr-bar-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Muscle Balance Week/All-time segmented control track (5px, mirrors
       --lb-seg-well / --pr-seg-well dark). */
    --mbr-seg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Muscle Balance YOU/BUDDY sub-section engraved well (5px, mirrors
       --wvc-sub-well dark). */
    --mbr-sub-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68), inset -5px -5px 9px
      rgba(255, 255, 255, 0.05), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Winning PPL category stronger orange glow (uses --accent-rgb, mirrors
       --wvc-winner-glow). */
    --mbr-winner-glow: 0 0 18px rgba(var(--accent-rgb), 0.55);
    /* Ideal ratio dashed reference line color at 33% (muted, dark-tuned). */
    --mbr-ideal-line: rgba(255, 255, 255, 0.18);

    /* ════════════════════════════════════════════════════════════════════════
       FASE 1 — BUDDY HUB OWN PLAYER CARD (closed + detail view)
       Additive tokens (dark theme). Mirror the :root FASE 1 OwnPlayerCard
       tokens with dark-tuned insets. --op-card-well copies the exact
       --op-hero-well dark shadow values (6px deep inset + hairline rim) so
       the closed card shares the same sculpted-recess language as the hero
       KPI / WVC / PR / streak outer cards. --op-xp-well / --op-stat-well /
       --op-detail-well copy the exact --wq-ring-well dark shadow values (5px
       deep inset + hairline rim). All glows use --accent-rgb (232,99,10)
       tuned for near-black (matches .wq-arc-glow / --op-trend-glow alpha).
       ════════════════════════════════════════════════════════════════════════ */
    /* Outer card engraved well — 6px deeper, mirrors --op-hero-well dark. */
    --op-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.74),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.025);
    /* XP bar track engraved well — 5px inset, mirrors --wq-ring-well dark. */
    --op-xp-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Stat pill engraved well — 5px inset, mirrors --wq-ring-well dark. */
    --op-stat-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Detail view chart container engraved well — 5px inset, mirrors
       --op-chart-well dark. Hosts spider chart + PPL donut + key-stat cells. */
    --op-detail-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Orange XP fill glow — soft warm halo on the XP bar fill (uses
       --accent-rgb). Tuned for near-black (matches .wq-arc-glow alpha). */
    --op-xp-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Avatar ring orange glow — soft warm halo on the avatar ring (uses
       --accent-rgb). Tuned for near-black. */
    --op-avatar-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Level medal orange glow — soft warm halo on the orange-gradient medal
       (uses --accent-rgb). Tuned for near-black. */
    --op-medal-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Spider chart fill orange glow — soft warm halo on the radar fill area
        (uses --accent-rgb). Tuned for near-black (matches .wq-arc-glow alpha). */
    --op-spider-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);

    /* ════════════════════════════════════════════════════════════════════════
       YOUR STATS REFINEMENT — OwnPlayerCardDetail 7-point upgrade
       Additive tokens (dark theme). Mirror the :root tokens with dark-tuned
       insets (5px deep inset + hairline rim, copies exact --wq-ring-well /
       --op-detail-well dark shadow values) so stat cells / donut / radar
       share the SAME sculpted-recess depth language on near-black. Toggle
       pills reuse existing --op-pill-raised / --op-pill-active-glow. All
       glows use --accent-rgb tuned for near-black.
       ════════════════════════════════════════════════════════════════════════ */
    /* Stat cell well — 5px deep inset, mirrors --op-detail-well dark exactly.
       Same depth for ALL stat cells (hero + secondary) + donut + radar. */
    --op-stat-cell-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Radar container well — 5px deep inset, mirrors --op-stat-cell-well. */
    --op-radar-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Hero metric typography — large prominent number for the hero stat. */
    --op-hero-metric-size: 3rem;
    --op-hero-metric-line: 1.05;
    --op-hero-metric-weight: 700;
    --op-hero-metric-tracking: -0.02em;
    /* Secondary stat typography — compact number for the 4 secondary stats. */
    --op-stat-secondary-size: 1.25rem;
    --op-stat-secondary-line: 1.2;
    --op-stat-secondary-weight: 600;
    /* Stat label typography — tiny uppercase muted label. */
    --op-stat-label-size: 0.625rem;
    --op-stat-label-tracking: 0.08em;
    --op-stat-label-weight: 600;
    /* PPL donut 0% grey fill — flat muted fill for empty slices (dark-tuned:
       lighter than light theme so it reads on near-black). */
    --ppl-empty-fill: rgba(255, 255, 255, 0.08);
    /* PPL legend colors — formalized rgb triplets (theme-agnostic). */
    --ppl-push-rgb: 232, 99, 10;
    --ppl-pull-rgb: 64, 140, 220;
    --ppl-legs-rgb: 120, 200, 140;
    /* Radar axis numeric value — smaller muted number next to axis name. */
    --op-radar-axis-value-size: 0.5625rem;
    --op-radar-axis-value-weight: 500;
    /* Coaching accent border — orange ring + soft glow (dark-tuned alpha). */
    --op-coaching-ring: 0 0 0 1.5px rgba(var(--accent-rgb), 0.6);
    --op-coaching-glow: 0 0 14px rgba(var(--accent-rgb), 0.22), 0 0 28px
      rgba(var(--accent-rgb), 0.1);

    /* ════════════════════════════════════════════════════════════════════════
        FASE 2 — BUDDY HUB VS-COMPARISON SHEET
       Additive tokens (dark theme). Mirror the :root Fase 2 tokens with
       dark-tuned insets. --vs-sheet-well copies the exact --op-card-well dark
       shadow values (6px deep inset + hairline rim) so the VS sheet shares
       the same sculpted-recess language as the OwnPlayerCard outer card.
       --vs-stat-well copies the exact --wq-ring-well dark shadow values (5px
       deep inset + hairline rim). Glows use --accent-rgb (orange, user side
       / winner) and --buddy-rgb (blue, buddy side) tuned for near-black
       (matches .wq-arc-glow / --op-spider-glow alpha).
       ════════════════════════════════════════════════════════════════════════ */
    /* Buddy-blue contrast color — formalized from PPL_RGB.pull (0,146,189).
       Mirrored from :root; theme-agnostic. */
    --buddy-rgb: 0, 146, 189;
    --buddy-hex: #0092bd;
    /* VS sheet background well — 6px deep engraved well, mirrors --op-card-well
       dark. Hosts the whole VS sheet surface as a sculpted recess. */
    --vs-sheet-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.74),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.025);
    /* VS spider buddy glow — soft blue halo on the buddy radar polygon (uses
       --buddy-rgb). Tuned for near-black (matches --op-spider-glow alpha). */
    --vs-spider-glow-buddy: 0 0 6px rgba(var(--buddy-rgb), 0.55), 0 0 14px
      rgba(var(--buddy-rgb), 0.28);
    /* VS stat winner glow — soft orange halo on the winning stat/category
       (uses --accent-rgb). Tuned for near-black. */
    --vs-stat-winner-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* VS stat row well — 5px engraved well, mirrors --wq-ring-well dark.
       Hosts each key-stat row as a sculpted recess. */
    --vs-stat-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);

    /* ════════════════════════════════════════════════════════════════════════
       MACROS — Nutrition dashboard (macro progress rings + meal sections +
       food library + nutrition streak + nutrition day-dots). Additive tokens
       (dark theme). Mirror the :root Macros tokens with dark-tuned insets.
       --mn-card-well copies the exact --op-card-well dark shadow values (6px
       deep inset + hairline rim); --mn-ring-well / --mn-meal-well / --mn-seg-
       well copy the exact --wq-ring-well dark shadow values (5px deep inset +
       hairline rim) so the Macros page shares the same sculpted-recess
       language as the weekly challenge / monthly goal / PPL wells on
       near-black. Macro arcs read --mn-arc-rgb per ring (orange/blue/green/
       amber) with --accent-rgb fallback.
       ════════════════════════════════════════════════════════════════════════ */
    /* Outer nutrition card well — 6px deep engraved well, mirrors --op-card-well
       dark. Hosts the whole Macros page surface as a sculpted recess. */
    --mn-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.74),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.025);
    /* Macro progress ring well — 5px engraved inset, copies the exact
       --wq-ring-well dark shadow values. Hosts the calorie ring + per-macro
       rings. */
    --mn-ring-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Meal section well — 5px engraved inset, mirrors --mn-ring-well dark.
       Hosts each meal section (ontbijt/lunch/diner/snack) as a sculpted card. */
    --mn-meal-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Food item row well — 4px engraved inset, mirrors --op-empty-well dark.
       Hosts each logged food / library food row as a quieter recess. */
    --mn-item-well:
      inset 4px 4px 8px rgba(0, 0, 0, 0.55),
      inset -4px -4px 8px rgba(255, 255, 255, 0.04),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Segmented control track well — 5px engraved inset, copies the exact
       --lb-seg-well dark shadow values. Hosts the meal/day + library/quick-add
       segmented controls. */
    --mn-seg-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Nutrition day-dot well — 3px engraved inset, mirrors --mw-tile-rest dark.
       Hosts each nutrition day-dot on the home page + weekly view. */
    --mn-dot-well: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px 5px
      rgba(255, 255, 255, 0.03);
    /* Macro arc glow — soft drop-shadow halo on the macro rings. Reads the
       per-macro --mn-arc-rgb set on each arc element (falls back to accent).
       Tuned for near-black (matches .wq-arc-glow alpha). */
    --mn-arc-glow: 0 0 6px rgba(var(--mn-arc-rgb, var(--accent-rgb)), 0.55), 0 0
      14px rgba(var(--mn-arc-rgb, var(--accent-rgb)), 0.28);
    /* Nutrition day-dot glow — soft warm halo on logged nutrition day-dots
       (uses --accent-rgb). Tuned for near-black. */
    --mn-dot-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Macro color triplets — theme-agnostic rgb triplets (mirrored from
       :root). Calories = accent orange, Protein = blue, Carbs = green,
       Fat = amber. */
    --mn-cal-rgb: 232, 99, 10;
    --mn-protein-rgb: 64, 140, 220;
    --mn-carbs-rgb: 120, 200, 140;
    --mn-fat-rgb: 210, 170, 70;
    /* Over-goal red — distinct from --destructive; a softer red for "over
       goal" macro/calorie states (tuned for near-black). */
    --mn-over-rgb: 220, 80, 70;

    /* ════════════════════════════════════════════════════════════════════════
       FASE 2 — UNIFIED PR-LADDER CHALLENGE MODEL + LIFECYCLE STATUS
       Additive tokens (dark theme). Mirror the :root Fase 2 tokens with
       dark-tuned insets. --ch-card-well copies the exact --pr-card-well dark
       shadow values (6px deep inset + hairline rim); --ch-metric-well /
       --ch-sub-well / --ch-bar-well copy the exact --wq-ring-well dark shadow
       values (5px deep inset + hairline rim) so the consolidated challenge
       card shares the same sculpted-recess language as the Fase 1 buddy
       cards on near-black. Glows use --accent-rgb (orange) or --buddy-rgb
       (blue) tuned for near-black (matches .wq-arc-glow / --op-spider-glow
       alpha). Lifecycle badge rgb triplets are theme-agnostic (mirrored).
       ════════════════════════════════════════════════════════════════════════ */
    /* Unified PR-ladder card outer well — 6px deep, mirrors --pr-card-well
       dark. Hosts the consolidated challenge card surface. */
    --ch-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.68),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Metric cell well — 5px engraved inset, copies exact --wq-ring-well dark
       shadow values. Hosts metriek / tijdsvenster / winvoorwaarde cells. */
    --ch-metric-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Opponent (buddy) sub-row well — 5px engraved inset, mirrors --wvc-sub-well
       dark. Hosts the buddy side of the ladder/balance comparison. */
    --ch-sub-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Progress bar track well — 5px engraved inset, mirrors --wvc-bar-well
       dark. Hosts the win-condition progress fill. */
    --ch-bar-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Active challenge orange glow — soft warm halo (uses --accent-rgb,
       mirrors --wvc-live-glow dark). */
    --ch-active-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    /* Winner side stronger orange glow (uses --accent-rgb, mirrors
       --wvc-winner-glow dark). */
    --ch-winner-glow: 0 0 18px rgba(var(--accent-rgb), 0.55);
    /* Opponent (buddy) side blue glow (uses --buddy-rgb, mirrors
       --vs-spider-glow-buddy dark). */
    --ch-buddy-glow: 0 0 6px rgba(var(--buddy-rgb), 0.55), 0 0 14px
      rgba(var(--buddy-rgb), 0.28);
    /* Rematch button breathing glow — accent gradient button halo (uses
       --accent-rgb, mirrors --op-pill-active-glow dark). */
    --ch-rematch-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Lifecycle status badge rgb triplets — theme-agnostic (mirrored from
       :root). voorgesteld = muted stone, geaccepteerd = buddy-blue, actief =
       orange, afgerond = green, afgewikkeld = neutral. */
    --lc-proposed-rgb: 140, 140, 140;
    --lc-accepted-rgb: 0, 146, 189;
    --lc-active-rgb: 232, 99, 10;
    --lc-done-rgb: 120, 200, 140;
    --lc-settled-rgb: 200, 200, 200;
    /* Lifecycle status badge well — 3px engraved inset, mirrors --mw-tile-rest
       dark. Hosts the status pill so it reads as a quiet sculpted chip. */
    --lc-badge-well: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px 5px
      rgba(255, 255, 255, 0.03);

    /* ════════════════════════════════════════════════════════════════════════
       FASE 3 — CHALLENGECENTRUM (status groups + filter + countdown + actions)
       Additive tokens (dark theme). Mirror the :root Fase 3 tokens with
       dark-tuned insets. --cc-group-well copies the exact --ch-card-well dark
       shadow values (6px deep inset + hairline rim); --cc-card-well /
       --cc-filter-well copy the exact --wq-ring-well dark shadow values (5px
       deep inset + hairline rim); --cc-countdown-well copies the exact
       --lc-badge-well dark values (3px inset). Glows use --accent-rgb (orange)
       or --buddy-rgb (blue) tuned for near-black. Status rgb triplets are
       theme-agnostic (mirrored from :root).
       ════════════════════════════════════════════════════════════════════════ */
    /* Status group accent rgb triplets — theme-agnostic (mirrored). */
    --cc-proposed-rgb: 140, 140, 140;
    --cc-active-rgb: 232, 99, 10;
    --cc-done-rgb: 120, 200, 140;
    /* Status group glows — dark-tuned (matches .wq-arc-glow alpha). */
    --cc-proposed-glow: 0 0 8px rgba(var(--cc-proposed-rgb), 0.35);
    --cc-active-glow: 0 0 12px rgba(var(--accent-rgb), 0.45);
    --cc-done-glow: 0 0 12px rgba(var(--cc-done-rgb), 0.4);
    /* Status group container well — 6px deep, mirrors --ch-card-well dark. */
    --cc-group-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.68),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Challenge card well — 5px engraved inset, copies exact --wq-ring-well
       dark shadow values. */
    --cc-card-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Status filter segmented track — 5px engraved inset, copies exact
       --lb-seg-well dark shadow values. */
    --cc-filter-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Filter active option glow — orange halo (mirrors --op-pill-active-glow
       dark). */
    --cc-filter-active-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Countdown timer chip well — 3px engraved inset, mirrors --lc-badge-well
       dark. */
    --cc-countdown-well: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px
      5px rgba(255, 255, 255, 0.03);
    /* Countdown urgent glow — orange halo (uses --accent-rgb). */
    --cc-countdown-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Action button glows — accept = orange, decline = muted red, settle =
       buddy-blue. Rematch reuses --ch-rematch-glow. */
    --cc-accept-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    --cc-decline-rgb: 210, 90, 80;
    --cc-decline-glow: 0 0 6px rgba(var(--cc-decline-rgb), 0.45);
    --cc-settle-glow: 0 0 6px rgba(var(--buddy-rgb), 0.55), 0 0 14px
      rgba(var(--buddy-rgb), 0.28);
    /* Disabled action state — muted text + reduced opacity. */
    --cc-disabled-rgb: 130, 130, 130;
    --cc-disabled-opacity: 0.45;

    /* ════════════════════════════════════════════════════════════════════════
       FASE 5 — GEDEELD PLAN (shared training plan)
       Additive tokens (dark theme). Mirror the :root Fase 5 tokens with
       dark-tuned insets. --sp-card-well copies the exact --ch-card-well dark
       shadow values (6px deep inset + hairline rim); --sp-day-well /
       --sp-goal-well / --sp-track-well copy the exact --cc-card-well /
       --cc-filter-well dark values (5px deep inset + hairline rim);
       --sp-empty-well copies the exact --cc-countdown-well dark values (3px
       inset). Glows use --accent-rgb (orange, self) or --buddy-rgb (blue,
       buddy) tuned for near-black.
       ════════════════════════════════════════════════════════════════════════ */
    /* Shared plan outer card well — 6px deep, mirrors --ch-card-well dark. */
    --sp-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.68),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Shared training day row well — 5px engraved inset, mirrors
       --cc-card-well dark. */
    --sp-day-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Joint goal cell well — 5px engraved inset, mirrors --cc-filter-well
       dark. */
    --sp-goal-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Joint progress track well — 5px engraved inset, mirrors --cc-filter-well
       dark. */
    --sp-track-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Progress fill glow — orange halo (uses --accent-rgb, mirrors
       --cc-accept-glow dark). */
    --sp-fill-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Per-buddy completion chip glows — self = orange (--accent-rgb), buddy =
       blue (--buddy-rgb). Dark-tuned alpha. */
    --sp-chip-self-glow: 0 0 6px rgba(var(--accent-rgb), 0.45);
    --sp-chip-buddy-glow: 0 0 6px rgba(var(--buddy-rgb), 0.45);
    /* Empty state well — 3px engraved inset, mirrors --cc-countdown-well
       dark. */
    --sp-empty-well: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px 5px
      rgba(255, 255, 255, 0.03);

    /* ════════════════════════════════════════════════════════════════════════
       COMPACT PERIOD SEGMENTED CONTROL — Progression stats cards
       Additive tokens (dark theme). Mirror the :root tokens with dark-tuned
       insets. --ps-seg-well copies the exact --lb-seg-well dark shadow values
       (5px deep inset + hairline rim) so the compact period track shares the
       same sculpted-recess language as the other segmented controls on
       near-black. Active period glow uses --accent-rgb tuned for near-black
       (matches --op-pill-active-glow dark alpha).
       ════════════════════════════════════════════════════════════════════════ */
    /* Segmented track well — slim engraved recess hosting the period options.
       Copies exact --lb-seg-well dark shadow values. */
    --ps-seg-well:
      inset 4px 4px 7px rgba(0, 0, 0, 0.68),
      inset -4px -4px 7px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Raised button shadow — subtle raised surface for inactive period
       buttons. Dark-tuned (subtle white highlight). */
    --ps-btn-raised: 2px 2px 4px rgba(0, 0, 0, 0.5), -2px -2px 4px
      rgba(255, 255, 255, 0.04);
    /* Active period glow — soft warm halo (uses --accent-rgb, mirrors
       --op-pill-active-glow dark). */
    --ps-btn-active-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Active period pressed shadow — engraved inset when pressed. */
    --ps-btn-pressed: inset 2px 2px 4px rgba(0, 0, 0, 0.6), inset -2px -2px 4px
      rgba(255, 255, 255, 0.03);

    /* ════════════════════════════════════════════════════════════════════════
       HOME WELCOME BLOCK — new-user hero (0 workouts)
       Additive tokens (dark theme). Mirror the :root welcome tokens with dark-
       tuned insets. --wb-card-well copies the exact --op-card-well dark shadow
       values (6px deep inset + hairline rim); --wb-icon-well copies the exact
       --wq-ring-well dark values (5px deep inset + hairline rim);
       --wb-eyebrow-well copies the exact --lc-badge-well dark values (3px
       inset). Glows use --accent-rgb tuned for near-black (matches
       --op-avatar-glow / --cc-accept-glow dark alpha).
       ════════════════════════════════════════════════════════════════════════ */
    /* Welcome hero card well — 6px deep engraved recess, mirrors --op-card-well
       dark. Hosts the whole welcome block surface as a sculpted recess. */
    --wb-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.74),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.025);
    /* Leading icon well — 5px engraved circular recess, copies exact
       --wq-ring-well dark shadow values. Hosts the dumbbell/start icon. */
    --wb-icon-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Leading icon glow — soft orange halo (uses --accent-rgb, mirrors
       --op-avatar-glow dark). */
    --wb-icon-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Eyebrow chip well — 3px engraved inset, mirrors --lc-badge-well dark. */
    --wb-eyebrow-well: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px
      5px rgba(255, 255, 255, 0.03);
    /* Primary CTA glow — soft orange breathing halo (uses --accent-rgb,
       mirrors --cc-accept-glow dark). */
    --wb-cta-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);

    /* ════════════════════════════════════════════════════════════════════════
       BLUEPRINT SHARING — public shared view + share/import CTAs
       Additive tokens (dark theme). Mirror the :root share tokens with dark-
       tuned insets. --sh-card-well copies the exact --op-card-well dark shadow
       values (6px deep inset + hairline rim); --sh-day-well / --sh-login-well
       copy the exact --wq-ring-well dark values (5px deep inset + hairline
       rim); --sh-spec-well / --sh-link-well copy the exact --op-empty-well dark
       values (4px inset); --sh-badge-well / --sh-eyebrow-well copy the exact
       --lc-badge-well dark values (3px inset). Public view accent = buddy-blue
       (--buddy-rgb); import/share CTAs use --accent-rgb (orange) tuned for
       near-black.
       ════════════════════════════════════════════════════════════════════════ */
    /* Public shared-view outer card well — 6px deep, mirrors --op-card-well
       dark. Hosts the whole public blueprint surface. */
    --sh-card-well:
      inset 6px 6px 11px rgba(0, 0, 0, 0.74),
      inset -6px -6px 11px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.025);
    /* Public shared-view header band — subtle blue-tinted surface (uses
       --buddy-rgb) so the read-only view reads as a "shared showcase". */
    --sh-header-rgb: 0, 146, 189;
    --sh-header-glow: 0 0 6px rgba(var(--buddy-rgb), 0.45), 0 0 14px
      rgba(var(--buddy-rgb), 0.22);
    /* Public badge chip well — 3px engraved inset, mirrors --lc-badge-well
       dark. Hosts the "Gedeeld plan" / "Alleen-lezen" pill. */
    --sh-badge-well: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px 5px
      rgba(255, 255, 255, 0.03);
    /* Read-only training day row well — 5px engraved recess, mirrors
       --cc-card-well dark. Hosts each day in the public view. */
    --sh-day-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Exercise spec cell well — 4px engraved inset, mirrors --op-empty-well
       dark. Hosts per-exercise specs in read-only. */
    --sh-spec-well:
      inset 4px 4px 8px rgba(0, 0, 0, 0.55), inset -4px -4px 8px
      rgba(255, 255, 255, 0.04), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Public eyebrow chip well — 3px engraved inset, mirrors --lc-badge-well
       dark. Hosts the "Gedeeld door {naam}" label. */
    --sh-eyebrow-well: inset 3px 3px 5px rgba(0, 0, 0, 0.48), inset -3px -3px
      5px rgba(255, 255, 255, 0.03);
    /* Import CTA glow — orange breathing halo (uses --accent-rgb, mirrors
       --cc-accept-glow dark). */
    --sh-import-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Share CTA glow — orange breathing halo (uses --accent-rgb, mirrors
       --cc-accept-glow dark). */
    --sh-share-glow: 0 0 6px rgba(var(--accent-rgb), 0.55), 0 0 14px
      rgba(var(--accent-rgb), 0.28);
    /* Share-link copy field well — 4px engraved inset, mirrors --mn-item-well
       dark. Hosts the read-only share URL. */
    --sh-link-well:
      inset 4px 4px 8px rgba(0, 0, 0, 0.55), inset -4px -4px 8px
      rgba(255, 255, 255, 0.04), inset 0 0 0 1px rgba(255, 255, 255, 0.02);
    /* Login-prompt banner well — 5px engraved recess, mirrors --wq-ring-well
       dark. Hosts the "Log in om te importeren" hint for visitors. */
    --sh-login-well:
      inset 5px 5px 9px rgba(0, 0, 0, 0.68),
      inset -5px -5px 9px rgba(255, 255, 255, 0.05),
      inset 0 0 0 1px rgba(255, 255, 255, 0.02);
  }

  * {
  border-color: oklch(var(--border));
}

  html,
  body,
  #root {
    /* Use a minimum height instead of a fixed height so content is never
       squeezed into a viewport-sized box. Each page carries its own bottom
       safe-area clearance, so the body no longer needs a fixed height or a
       global bottom inset. */
    min-height: 100%;
    min-height: 100dvh;
    /* Defense-in-depth against horizontal overflow being exposed as a black
       bar on the right when iOS auto-zooms into a focused input. Inner
       vertical scrolling is unaffected. */
    overflow-x: hidden;
  }

  body {
  background-color: oklch(var(--background));
  color: oklch(var(--foreground));
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
      "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans",
      "Helvetica Neue", sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    -webkit-tap-highlight-color: transparent;
}

  /* Enhanced Typography Hierarchy with Better Contrast */
  h1 {
  font-size: 1.5rem;
  line-height: 2rem;
  font-weight: 700;
  letter-spacing: -0.025em;
    line-height: 1.2;
    color: oklch(var(--foreground));
}

  h2 {
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 600;
  letter-spacing: -0.025em;
    line-height: 1.3;
    color: oklch(var(--foreground));
}

  h3 {
  font-size: 1.125rem;
  line-height: 1.75rem;
  font-weight: 600;
    line-height: 1.4;
    color: oklch(var(--foreground));
}

  h4 {
  font-size: 1rem;
  line-height: 1.5rem;
  font-weight: 600;
    line-height: 1.4;
    color: oklch(var(--foreground));
}

  /* Improved Text Contrast Hierarchy */

  /* Prevent zoom on input focus for mobile */
  input[type="text"],
  input[type="number"],
  input[type="email"],
  input[type="tel"],
  input[type="password"],
  textarea,
  select {
    font-size: 16px;
  }

  /* PWA standalone mode adjustments */
  @media (display-mode: standalone) {
    body {
      -moz-user-select: none;
           user-select: none;
      -webkit-user-select: none;
    }
  }

  /* Mobile scroll optimizations — apply only to scrollable containers, not globally */
  .scrollable {
    -webkit-overflow-scrolling: touch;
    overflow-y: auto;
  }

  /* Hide scrollbar while keeping scroll functional (touch/swipe only) */
  .no-scrollbar {
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .no-scrollbar::-webkit-scrollbar {
    display: none;
  }
.container {
  width: 100%;
}
@media (min-width: 640px) {

  .container {
    max-width: 640px;
  }
}
@media (min-width: 768px) {

  .container {
    max-width: 768px;
  }
}
@media (min-width: 1024px) {

  .container {
    max-width: 1024px;
  }
}
@media (min-width: 1280px) {

  .container {
    max-width: 1280px;
  }
}
@media (min-width: 1536px) {

  .container {
    max-width: 1536px;
  }
}
/* Remove all animations from AlertDialog components for instant open/close */
[role="alertdialog"] {
    animation: none !important;
    transition: none !important;
  }
[role="alertdialog"] * {
    animation: none !important;
    transition: none !important;
  }
/* Target Radix UI AlertDialog overlay specifically */
[data-radix-alert-dialog-overlay] {
    animation: none !important;
    transition: none !important;
  }
/* Target Radix UI AlertDialog content specifically */
[data-radix-alert-dialog-content] {
    animation: none !important;
    transition: none !important;
  }
/* Override any data-state animations for AlertDialog */
[role="alertdialog"][data-state="open"],
  [role="alertdialog"][data-state="closed"] {
    animation: none !important;
    transition: none !important;
  }
[data-radix-alert-dialog-overlay][data-state="open"],
  [data-radix-alert-dialog-overlay][data-state="closed"] {
    animation: none !important;
    transition: none !important;
  }
[data-radix-alert-dialog-content][data-state="open"],
  [data-radix-alert-dialog-content][data-state="closed"] {
    animation: none !important;
    transition: none !important;
  }
/* Analytics chart placeholder styles */
/* ═══════════════════════════════════════════════════════════════════════════
     COMPACT PERIOD SEGMENTED CONTROL — Progression stats cards
     One slim pill-shaped segmented control replacing the four bulky inline
     period selectors (Muscle Balance / OneRM / Fatigue vs Fitness / PPL
     Balance). Same compact style + same options (7D, 1M, 6M, 1Y, All) on every
     card; each card keeps its own independent period via its own state.
     Track = engraved inset well (--ps-seg-well); inactive buttons = small
     raised neumorphic pills (--ps-btn-raised); active = orange accent glow
     (--ps-btn-active-glow) + accent text. aria-pressed + keyboard focus ring.
     On narrow phones (< 420px) the row collapses into a small dropdown so
     nothing overflows (see @media below).
     ═══════════════════════════════════════════════════════════════════════════ */
.period-seg {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border-radius: 9999px;
    background-color: oklch(var(--card));
    box-shadow: var(--ps-seg-well);
    /* Prevent the compact row from forcing a card wider than its container. */
    max-width: 100%;
    flex-wrap: nowrap;
  }
.period-seg__btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    min-height: 1.5rem;
    padding: 0 0.5rem;
    border: none;
    border-radius: 9999px;
    background: transparent;
    color: oklch(var(--muted-foreground));
    font-family: var(--font-display);
    font-size: 0.6875rem;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.01em;
    cursor: pointer;
    box-shadow: var(--ps-btn-raised);
    transition: box-shadow 180ms cubic-bezier(0.4, 0, 0.2, 1), color 180ms
      cubic-bezier(0.4, 0, 0.2, 1), background-color 180ms
      cubic-bezier(0.4, 0, 0.2, 1);
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }
.period-seg__btn:hover {
    color: oklch(var(--foreground));
  }
.period-seg__btn:active {
    box-shadow: var(--ps-btn-pressed);
  }
/* Active period — orange accent glow + accent text so the selected period
     reads clearly at a glance. */
.period-seg__btn[aria-pressed="true"],
  .period-seg__btn--active {
    background-color: oklch(var(--accent) / 0.14);
    color: var(--accent-hex);
    box-shadow: var(--ps-btn-active-glow);
  }
/* Keyboard focus ring — visible outline for keyboard/touch accessibility. */
.period-seg__btn:focus-visible {
    outline: 2px solid oklch(var(--ring));
    outline-offset: 2px;
  }
/* Dropdown — hidden by default (only shown on narrow phones). Small compact
     select styled to match the neumorphic language. */
.period-seg__dropdown {
    display: none;
    align-items: center;
    min-height: 1.75rem;
    padding: 0 0.5rem;
    border: none;
    border-radius: 9999px;
    background-color: oklch(var(--card));
    color: oklch(var(--foreground));
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 600;
    box-shadow: var(--ps-seg-well);
    cursor: pointer;
  }
/* Narrow phones — collapse the segmented row into a small dropdown so the
     five options never overflow the card. The frontend renders a compact
     select (same options, same active period) in this breakpoint. Placed
     after the standalone .period-seg__dropdown rule so its display: inline-flex
     wins at equal specificity on narrow screens. */
@media (max-width: 419px) {
    .period-seg {
      display: none;
    }
    .period-seg__dropdown {
      display: inline-flex;
    }
  }
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
.pointer-events-none {
  pointer-events: none;
}
.pointer-events-auto {
  pointer-events: auto;
}
.visible {
  visibility: visible;
}
.invisible {
  visibility: hidden;
}
.collapse {
  visibility: collapse;
}
.static {
  position: static;
}
.fixed {
  position: fixed;
}
.absolute {
  position: absolute;
}
.relative {
  position: relative;
}
.sticky {
  position: sticky;
}
.inset-0 {
  inset: 0px;
}
.inset-x-0 {
  left: 0px;
  right: 0px;
}
.inset-y-0 {
  top: 0px;
  bottom: 0px;
}
.-bottom-0\.5 {
  bottom: -0.125rem;
}
.-bottom-1\.5 {
  bottom: -0.375rem;
}
.-right-0\.5 {
  right: -0.125rem;
}
.-right-1 {
  right: -0.25rem;
}
.-right-1\.5 {
  right: -0.375rem;
}
.-right-10 {
  right: -2.5rem;
}
.-right-12 {
  right: -3rem;
}
.-right-4 {
  right: -1rem;
}
.-top-1 {
  top: -0.25rem;
}
.-top-1\.5 {
  top: -0.375rem;
}
.-top-10 {
  top: -2.5rem;
}
.-top-12 {
  top: -3rem;
}
.-top-4 {
  top: -1rem;
}
.bottom-0 {
  bottom: 0px;
}
.bottom-2 {
  bottom: 0.5rem;
}
.bottom-20 {
  bottom: 5rem;
}
.bottom-4 {
  bottom: 1rem;
}
.left-0 {
  left: 0px;
}
.left-1\/2 {
  left: 50%;
}
.left-2 {
  left: 0.5rem;
}
.left-3 {
  left: 0.75rem;
}
.left-5 {
  left: 1.25rem;
}
.left-\[50\%\] {
  left: 50%;
}
.right-0 {
  right: 0px;
}
.right-1\.5 {
  right: 0.375rem;
}
.right-2 {
  right: 0.5rem;
}
.right-3 {
  right: 0.75rem;
}
.right-4 {
  right: 1rem;
}
.top-0 {
  top: 0px;
}
.top-1 {
  top: 0.25rem;
}
.top-1\.5 {
  top: 0.375rem;
}
.top-1\/2 {
  top: 50%;
}
.top-12 {
  top: 3rem;
}
.top-2 {
  top: 0.5rem;
}
.top-24 {
  top: 6rem;
}
.top-3 {
  top: 0.75rem;
}
.top-4 {
  top: 1rem;
}
.top-5 {
  top: 1.25rem;
}
.top-\[50\%\] {
  top: 50%;
}
.top-full {
  top: 100%;
}
.z-10 {
  z-index: 10;
}
.z-20 {
  z-index: 20;
}
.z-30 {
  z-index: 30;
}
.z-40 {
  z-index: 40;
}
.z-50 {
  z-index: 50;
}
.z-\[110\] {
  z-index: 110;
}
.z-\[120\] {
  z-index: 120;
}
.z-\[130\] {
  z-index: 130;
}
.z-\[140\] {
  z-index: 140;
}
.z-\[200\] {
  z-index: 200;
}
.z-\[60\] {
  z-index: 60;
}
.z-\[9999\] {
  z-index: 9999;
}
.col-span-2 {
  grid-column: span 2 / span 2;
}
.col-span-full {
  grid-column: 1 / -1;
}
.col-start-2 {
  grid-column-start: 2;
}
.row-span-2 {
  grid-row: span 2 / span 2;
}
.row-start-1 {
  grid-row-start: 1;
}
.m-0 {
  margin: 0px;
}
.m-auto {
  margin: auto;
}
.-mx-1 {
  margin-left: -0.25rem;
  margin-right: -0.25rem;
}
.-mx-3 {
  margin-left: -0.75rem;
  margin-right: -0.75rem;
}
.-my-1 {
  margin-top: -0.25rem;
  margin-bottom: -0.25rem;
}
.mx-2 {
  margin-left: 0.5rem;
  margin-right: 0.5rem;
}
.mx-6 {
  margin-left: 1.5rem;
  margin-right: 1.5rem;
}
.mx-auto {
  margin-left: auto;
  margin-right: auto;
}
.my-1 {
  margin-top: 0.25rem;
  margin-bottom: 0.25rem;
}
.-ml-0\.5 {
  margin-left: -0.125rem;
}
.-mr-1 {
  margin-right: -0.25rem;
}
.-mt-1 {
  margin-top: -0.25rem;
}
.mb-0\.5 {
  margin-bottom: 0.125rem;
}
.mb-1 {
  margin-bottom: 0.25rem;
}
.mb-1\.5 {
  margin-bottom: 0.375rem;
}
.mb-10 {
  margin-bottom: 2.5rem;
}
.mb-2 {
  margin-bottom: 0.5rem;
}
.mb-3 {
  margin-bottom: 0.75rem;
}
.mb-4 {
  margin-bottom: 1rem;
}
.mb-5 {
  margin-bottom: 1.25rem;
}
.mb-6 {
  margin-bottom: 1.5rem;
}
.mb-7 {
  margin-bottom: 1.75rem;
}
.mb-8 {
  margin-bottom: 2rem;
}
.ml-0\.5 {
  margin-left: 0.125rem;
}
.ml-1 {
  margin-left: 0.25rem;
}
.ml-2 {
  margin-left: 0.5rem;
}
.ml-6 {
  margin-left: 1.5rem;
}
.ml-auto {
  margin-left: auto;
}
.mr-1 {
  margin-right: 0.25rem;
}
.mr-2 {
  margin-right: 0.5rem;
}
.mt-0 {
  margin-top: 0px;
}
.mt-0\.5 {
  margin-top: 0.125rem;
}
.mt-1 {
  margin-top: 0.25rem;
}
.mt-1\.5 {
  margin-top: 0.375rem;
}
.mt-12 {
  margin-top: 3rem;
}
.mt-16 {
  margin-top: 4rem;
}
.mt-2 {
  margin-top: 0.5rem;
}
.mt-2\.5 {
  margin-top: 0.625rem;
}
.mt-3 {
  margin-top: 0.75rem;
}
.mt-4 {
  margin-top: 1rem;
}
.mt-5 {
  margin-top: 1.25rem;
}
.mt-6 {
  margin-top: 1.5rem;
}
.mt-8 {
  margin-top: 2rem;
}
.mt-auto {
  margin-top: auto;
}
.line-clamp-1 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
}
.line-clamp-2 {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}
.block {
  display: block;
}
.inline-block {
  display: inline-block;
}
.inline {
  display: inline;
}
.flex {
  display: flex;
}
.inline-flex {
  display: inline-flex;
}
.table {
  display: table;
}
.grid {
  display: grid;
}
.hidden {
  display: none;
}
.aspect-\[3\/4\] {
  aspect-ratio: 3/4;
}
.aspect-square {
  aspect-ratio: 1 / 1;
}
.size-2 {
  width: 0.5rem;
  height: 0.5rem;
}
.size-2\.5 {
  width: 0.625rem;
  height: 0.625rem;
}
.size-3\.5 {
  width: 0.875rem;
  height: 0.875rem;
}
.size-4 {
  width: 1rem;
  height: 1rem;
}
.size-5 {
  width: 1.25rem;
  height: 1.25rem;
}
.size-7 {
  width: 1.75rem;
  height: 1.75rem;
}
.size-8 {
  width: 2rem;
  height: 2rem;
}
.size-9 {
  width: 2.25rem;
  height: 2.25rem;
}
.size-full {
  width: 100%;
  height: 100%;
}
.\!h-7 {
  height: 1.75rem !important;
}
.\!h-\[34px\] {
  height: 34px !important;
}
.h-1 {
  height: 0.25rem;
}
.h-1\.5 {
  height: 0.375rem;
}
.h-10 {
  height: 2.5rem;
}
.h-11 {
  height: 2.75rem;
}
.h-12 {
  height: 3rem;
}
.h-14 {
  height: 3.5rem;
}
.h-16 {
  height: 4rem;
}
.h-2 {
  height: 0.5rem;
}
.h-2\.5 {
  height: 0.625rem;
}
.h-20 {
  height: 5rem;
}
.h-24 {
  height: 6rem;
}
.h-28 {
  height: 7rem;
}
.h-3 {
  height: 0.75rem;
}
.h-3\.5 {
  height: 0.875rem;
}
.h-4 {
  height: 1rem;
}
.h-40 {
  height: 10rem;
}
.h-5 {
  height: 1.25rem;
}
.h-6 {
  height: 1.5rem;
}
.h-7 {
  height: 1.75rem;
}
.h-8 {
  height: 2rem;
}
.h-9 {
  height: 2.25rem;
}
.h-\[1\.15rem\] {
  height: 1.15rem;
}
.h-\[14px\] {
  height: 14px;
}
.h-\[180px\] {
  height: 180px;
}
.h-\[85vh\] {
  height: 85vh;
}
.h-\[calc\(100vh-120px\)\] {
  height: calc(100vh - 120px);
}
.h-\[calc\(100vh-180px\)\] {
  height: calc(100vh - 180px);
}
.h-\[var\(--radix-select-trigger-height\)\] {
  height: var(--radix-select-trigger-height);
}
.h-auto {
  height: auto;
}
.h-full {
  height: 100%;
}
.h-px {
  height: 1px;
}
.h-screen {
  height: 100vh;
}
.max-h-56 {
  max-height: 14rem;
}
.max-h-64 {
  max-height: 16rem;
}
.max-h-72 {
  max-height: 18rem;
}
.max-h-\[50vh\] {
  max-height: 50vh;
}
.max-h-\[800px\] {
  max-height: 800px;
}
.max-h-\[85vh\] {
  max-height: 85vh;
}
.max-h-\[90vh\] {
  max-height: 90vh;
}
.max-h-\[92vh\] {
  max-height: 92vh;
}
.min-h-0 {
  min-height: 0px;
}
.min-h-16 {
  min-height: 4rem;
}
.min-h-4 {
  min-height: 1rem;
}
.min-h-\[120px\] {
  min-height: 120px;
}
.min-h-\[14px\] {
  min-height: 14px;
}
.min-h-\[2\.5rem\] {
  min-height: 2.5rem;
}
.min-h-\[20px\] {
  min-height: 20px;
}
.min-h-\[44px\] {
  min-height: 44px;
}
.min-h-\[68px\] {
  min-height: 68px;
}
.min-h-\[80px\] {
  min-height: 80px;
}
.min-h-screen {
  min-height: 100vh;
}
.\!w-7 {
  width: 1.75rem !important;
}
.w-1 {
  width: 0.25rem;
}
.w-1\.5 {
  width: 0.375rem;
}
.w-1\/2 {
  width: 50%;
}
.w-1\/3 {
  width: 33.333333%;
}
.w-10 {
  width: 2.5rem;
}
.w-11 {
  width: 2.75rem;
}
.w-12 {
  width: 3rem;
}
.w-14 {
  width: 3.5rem;
}
.w-16 {
  width: 4rem;
}
.w-2 {
  width: 0.5rem;
}
.w-2\.5 {
  width: 0.625rem;
}
.w-2\/3 {
  width: 66.666667%;
}
.w-20 {
  width: 5rem;
}
.w-24 {
  width: 6rem;
}
.w-28 {
  width: 7rem;
}
.w-3 {
  width: 0.75rem;
}
.w-3\.5 {
  width: 0.875rem;
}
.w-3\/4 {
  width: 75%;
}
.w-32 {
  width: 8rem;
}
.w-4 {
  width: 1rem;
}
.w-40 {
  width: 10rem;
}
.w-44 {
  width: 11rem;
}
.w-48 {
  width: 12rem;
}
.w-5 {
  width: 1.25rem;
}
.w-6 {
  width: 1.5rem;
}
.w-64 {
  width: 16rem;
}
.w-7 {
  width: 1.75rem;
}
.w-72 {
  width: 18rem;
}
.w-8 {
  width: 2rem;
}
.w-9 {
  width: 2.25rem;
}
.w-\[100px\] {
  width: 100px;
}
.w-\[14px\] {
  width: 14px;
}
.w-\[180px\] {
  width: 180px;
}
.w-\[90\%\] {
  width: 90%;
}
.w-\[98\%\] {
  width: 98%;
}
.w-\[calc\(100vw-2rem\)\] {
  width: calc(100vw - 2rem);
}
.w-fit {
  width: -moz-fit-content;
  width: fit-content;
}
.w-full {
  width: 100%;
}
.w-px {
  width: 1px;
}
.min-w-0 {
  min-width: 0px;
}
.min-w-10 {
  min-width: 2.5rem;
}
.min-w-8 {
  min-width: 2rem;
}
.min-w-9 {
  min-width: 2.25rem;
}
.min-w-\[140px\] {
  min-width: 140px;
}
.min-w-\[8rem\] {
  min-width: 8rem;
}
.min-w-\[var\(--radix-select-trigger-width\)\] {
  min-width: var(--radix-select-trigger-width);
}
.max-w-2xl {
  max-width: 42rem;
}
.max-w-5xl {
  max-width: 64rem;
}
.max-w-\[220px\] {
  max-width: 220px;
}
.max-w-\[240px\] {
  max-width: 240px;
}
.max-w-\[280px\] {
  max-width: 280px;
}
.max-w-\[300px\] {
  max-width: 300px;
}
.max-w-\[340px\] {
  max-width: 340px;
}
.max-w-\[360px\] {
  max-width: 360px;
}
.max-w-\[5\.5rem\] {
  max-width: 5.5rem;
}
.max-w-\[600px\] {
  max-width: 600px;
}
.max-w-\[calc\(100\%-2rem\)\] {
  max-width: calc(100% - 2rem);
}
.max-w-\[calc\(100vw-2rem\)\] {
  max-width: calc(100vw - 2rem);
}
.max-w-full {
  max-width: 100%;
}
.max-w-lg {
  max-width: 32rem;
}
.max-w-md {
  max-width: 28rem;
}
.max-w-sm {
  max-width: 24rem;
}
.max-w-xs {
  max-width: 20rem;
}
.flex-1 {
  flex: 1 1 0%;
}
.flex-\[2\] {
  flex: 2;
}
.flex-shrink {
  flex-shrink: 1;
}
.flex-shrink-0 {
  flex-shrink: 0;
}
.shrink {
  flex-shrink: 1;
}
.shrink-0 {
  flex-shrink: 0;
}
.grow {
  flex-grow: 1;
}
.-translate-x-1\/2 {
  --tw-translate-x: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-y-1\/2 {
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-x-\[-50\%\] {
  --tw-translate-x: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-y-\[-50\%\] {
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.translate-y-\[calc\(-50\%_-_2px\)\] {
  --tw-translate-y: calc(-50% - 2px);
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-180 {
  --tw-rotate: 180deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-45 {
  --tw-rotate: 45deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.rotate-\[-90deg\] {
  --tw-rotate: -90deg;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-105 {
  --tw-scale-x: 1.05;
  --tw-scale-y: 1.05;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.scale-\[1\.02\] {
  --tw-scale-x: 1.02;
  --tw-scale-y: 1.02;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.transform {
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
@keyframes ping {

  75%, 100% {
    transform: scale(2);
    opacity: 0;
  }
}
.animate-ping {
  animation: ping 1s cubic-bezier(0, 0, 0.2, 1) infinite;
}
@keyframes pulse {

  50% {
    opacity: .5;
  }
}
.animate-pulse {
  animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes spin {

  to {
    transform: rotate(360deg);
  }
}
.animate-spin {
  animation: spin 1s linear infinite;
}
.cursor-default {
  cursor: default;
}
.cursor-help {
  cursor: help;
}
.cursor-not-allowed {
  cursor: not-allowed;
}
.cursor-pointer {
  cursor: pointer;
}
.touch-none {
  touch-action: none;
}
.touch-manipulation {
  touch-action: manipulation;
}
.select-none {
  -webkit-user-select: none;
     -moz-user-select: none;
          user-select: none;
}
.resize-none {
  resize: none;
}
.resize {
  resize: both;
}
.scroll-my-1 {
  scroll-margin-top: 0.25rem;
  scroll-margin-bottom: 0.25rem;
}
.scroll-mt-4 {
  scroll-margin-top: 1rem;
}
.auto-rows-min {
  grid-auto-rows: min-content;
}
.grid-cols-1 {
  grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-cols-3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.grid-cols-4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.grid-cols-7 {
  grid-template-columns: repeat(7, minmax(0, 1fr));
}
.grid-cols-\[0_1fr\] {
  grid-template-columns: 0 1fr;
}
.grid-rows-\[auto_auto\] {
  grid-template-rows: auto auto;
}
.flex-row {
  flex-direction: row;
}
.flex-col {
  flex-direction: column;
}
.flex-col-reverse {
  flex-direction: column-reverse;
}
.flex-wrap {
  flex-wrap: wrap;
}
.content-start {
  align-content: flex-start;
}
.items-start {
  align-items: flex-start;
}
.items-end {
  align-items: flex-end;
}
.items-center {
  align-items: center;
}
.items-baseline {
  align-items: baseline;
}
.items-stretch {
  align-items: stretch;
}
.justify-end {
  justify-content: flex-end;
}
.justify-center {
  justify-content: center;
}
.justify-between {
  justify-content: space-between;
}
.justify-items-start {
  justify-items: start;
}
.gap-0 {
  gap: 0px;
}
.gap-0\.5 {
  gap: 0.125rem;
}
.gap-1 {
  gap: 0.25rem;
}
.gap-1\.5 {
  gap: 0.375rem;
}
.gap-2 {
  gap: 0.5rem;
}
.gap-2\.5 {
  gap: 0.625rem;
}
.gap-3 {
  gap: 0.75rem;
}
.gap-4 {
  gap: 1rem;
}
.gap-5 {
  gap: 1.25rem;
}
.gap-6 {
  gap: 1.5rem;
}
.gap-x-2 {
  -moz-column-gap: 0.5rem;
       column-gap: 0.5rem;
}
.gap-x-4 {
  -moz-column-gap: 1rem;
       column-gap: 1rem;
}
.gap-y-0\.5 {
  row-gap: 0.125rem;
}
.gap-y-1 {
  row-gap: 0.25rem;
}
.space-y-0 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0px * var(--tw-space-y-reverse));
}
.space-y-0\.5 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(0.125rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.125rem * var(--tw-space-y-reverse));
}
.space-y-1 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
}
.space-y-1\.5 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(0.375rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.375rem * var(--tw-space-y-reverse));
}
.space-y-2 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
.space-y-2\.5 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(0.625rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.625rem * var(--tw-space-y-reverse));
}
.space-y-3 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(0.75rem * var(--tw-space-y-reverse));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.space-y-5 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.25rem * var(--tw-space-y-reverse));
}
.space-y-6 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
}
.space-y-7 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(1.75rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(1.75rem * var(--tw-space-y-reverse));
}
.space-y-8 > :not([hidden]) ~ :not([hidden]) {
  --tw-space-y-reverse: 0;
  margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
  margin-bottom: calc(2rem * var(--tw-space-y-reverse));
}
.self-start {
  align-self: flex-start;
}
.self-center {
  align-self: center;
}
.self-stretch {
  align-self: stretch;
}
.justify-self-end {
  justify-self: end;
}
.overflow-hidden {
  overflow: hidden;
}
.overflow-visible {
  overflow: visible;
}
.overflow-y-auto {
  overflow-y: auto;
}
.overflow-x-hidden {
  overflow-x: hidden;
}
.overscroll-contain {
  overscroll-behavior: contain;
}
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.whitespace-normal {
  white-space: normal;
}
.whitespace-nowrap {
  white-space: nowrap;
}
.text-balance {
  text-wrap: balance;
}
.break-words {
  overflow-wrap: break-word;
}
.break-all {
  word-break: break-all;
}
.\!rounded-lg {
  border-radius: var(--radius) !important;
}
.rounded {
  border-radius: 0.25rem;
}
.rounded-2xl {
  border-radius: 1rem;
}
.rounded-3xl {
  border-radius: 1.5rem;
}
.rounded-\[10px\] {
  border-radius: 10px;
}
.rounded-\[2px\] {
  border-radius: 2px;
}
.rounded-\[inherit\] {
  border-radius: inherit;
}
.rounded-full {
  border-radius: 9999px;
}
.rounded-lg {
  border-radius: var(--radius);
}
.rounded-md {
  border-radius: calc(var(--radius) - 2px);
}
.rounded-sm {
  border-radius: calc(var(--radius) - 4px);
}
.rounded-xl {
  border-radius: 0.75rem;
}
.rounded-t-2xl {
  border-top-left-radius: 1rem;
  border-top-right-radius: 1rem;
}
.rounded-t-3xl {
  border-top-left-radius: 1.5rem;
  border-top-right-radius: 1.5rem;
}
.border {
  border-width: 1px;
}
.border-0 {
  border-width: 0px;
}
.border-2 {
  border-width: 2px;
}
.border-4 {
  border-width: 4px;
}
.border-b {
  border-bottom-width: 1px;
}
.border-l {
  border-left-width: 1px;
}
.border-l-2 {
  border-left-width: 2px;
}
.border-l-\[3px\] {
  border-left-width: 3px;
}
.border-r {
  border-right-width: 1px;
}
.border-t {
  border-top-width: 1px;
}
.border-solid {
  border-style: solid;
}
.border-none {
  border-style: none;
}
.border-\[oklch\(var\(--accent\)\)\] {
  border-color: oklch(var(--accent));
}
.border-accent {
  border-color: oklch(var(--accent));
}
.border-border {
  border-color: oklch(var(--border));
}
.border-current {
  border-color: currentColor;
}
.border-green-500 {
  --tw-border-opacity: 1;
  border-color: rgb(34 197 94 / var(--tw-border-opacity, 1));
}
.border-input {
  border-color: oklch(var(--input));
}
.border-red-500\/30 {
  border-color: rgb(239 68 68 / 0.3);
}
.border-transparent {
  border-color: transparent;
}
.border-l-transparent {
  border-left-color: transparent;
}
.border-r-transparent {
  border-right-color: transparent;
}
.border-t-accent {
  border-top-color: oklch(var(--accent));
}
.border-t-current {
  border-top-color: currentColor;
}
.border-t-transparent {
  border-top-color: transparent;
}
.bg-\[oklch\(0\.75_0\.05_40\/0\.15\)\] {
  background-color: oklch(0.75 0.05 40/0.15);
}
.bg-\[rgba\(120\2c 200\2c 140\2c 0\.18\)\] {
  background-color: rgba(120,200,140,0.18);
}
.bg-\[rgba\(210\2c 90\2c 80\2c 0\.18\)\] {
  background-color: rgba(210,90,80,0.18);
}
.bg-\[rgba\(64\2c 140\2c 220\2c 0\.18\)\] {
  background-color: rgba(64,140,220,0.18);
}
.bg-\[rgba\(var\(--accent-rgb\)\2c 0\.18\)\] {
  background-color: rgba(var(--accent-rgb),0.18);
}
.bg-\[var\(--accent-hex\)\] {
  background-color: var(--accent-hex);
}
.bg-accent {
  background-color: oklch(var(--accent));
}
.bg-background {
  background-color: oklch(var(--background));
}
.bg-black\/50 {
  background-color: rgb(0 0 0 / 0.5);
}
.bg-black\/60 {
  background-color: rgb(0 0 0 / 0.6);
}
.bg-black\/70 {
  background-color: rgb(0 0 0 / 0.7);
}
.bg-blue-500\/20 {
  background-color: rgb(59 130 246 / 0.2);
}
.bg-border {
  background-color: oklch(var(--border));
}
.bg-card {
  background-color: oklch(var(--card));
}
.bg-current {
  background-color: currentColor;
}
.bg-cyan-500\/20 {
  background-color: rgb(6 182 212 / 0.2);
}
.bg-destructive {
  background-color: oklch(var(--destructive));
}
.bg-emerald-400 {
  --tw-bg-opacity: 1;
  background-color: rgb(52 211 153 / var(--tw-bg-opacity, 1));
}
.bg-emerald-500\/15 {
  background-color: rgb(16 185 129 / 0.15);
}
.bg-gray-500\/20 {
  background-color: rgb(107 114 128 / 0.2);
}
.bg-green-400 {
  --tw-bg-opacity: 1;
  background-color: rgb(74 222 128 / var(--tw-bg-opacity, 1));
}
.bg-green-500 {
  --tw-bg-opacity: 1;
  background-color: rgb(34 197 94 / var(--tw-bg-opacity, 1));
}
.bg-green-500\/20 {
  background-color: rgb(34 197 94 / 0.2);
}
.bg-muted {
  background-color: oklch(var(--muted));
}
.bg-orange-500\/20 {
  background-color: rgb(249 115 22 / 0.2);
}
.bg-pink-500\/20 {
  background-color: rgb(236 72 153 / 0.2);
}
.bg-popover {
  background-color: oklch(var(--popover));
}
.bg-primary {
  background-color: oklch(var(--primary));
}
.bg-purple-500\/20 {
  background-color: rgb(168 85 247 / 0.2);
}
.bg-red-500\/20 {
  background-color: rgb(239 68 68 / 0.2);
}
.bg-red-600\/20 {
  background-color: rgb(220 38 38 / 0.2);
}
.bg-secondary {
  background-color: oklch(var(--secondary));
}
.bg-teal-500\/20 {
  background-color: rgb(20 184 166 / 0.2);
}
.bg-transparent {
  background-color: transparent;
}
.bg-yellow-400 {
  --tw-bg-opacity: 1;
  background-color: rgb(250 204 21 / var(--tw-bg-opacity, 1));
}
.bg-yellow-500\/20 {
  background-color: rgb(234 179 8 / 0.2);
}
.bg-gradient-to-br {
  background-image: linear-gradient(to bottom right, var(--tw-gradient-stops));
}
.fill-current {
  fill: currentColor;
}
.fill-primary {
  fill: oklch(var(--primary));
}
.fill-white {
  fill: #fff;
}
.object-contain {
  -o-object-fit: contain;
     object-fit: contain;
}
.object-cover {
  -o-object-fit: cover;
     object-fit: cover;
}
.p-0 {
  padding: 0px;
}
.p-0\.5 {
  padding: 0.125rem;
}
.p-1 {
  padding: 0.25rem;
}
.p-1\.5 {
  padding: 0.375rem;
}
.p-10 {
  padding: 2.5rem;
}
.p-12 {
  padding: 3rem;
}
.p-2 {
  padding: 0.5rem;
}
.p-2\.5 {
  padding: 0.625rem;
}
.p-3 {
  padding: 0.75rem;
}
.p-3\.5 {
  padding: 0.875rem;
}
.p-4 {
  padding: 1rem;
}
.p-5 {
  padding: 1.25rem;
}
.p-6 {
  padding: 1.5rem;
}
.p-8 {
  padding: 2rem;
}
.p-px {
  padding: 1px;
}
.\!px-2 {
  padding-left: 0.5rem !important;
  padding-right: 0.5rem !important;
}
.px-0\.5 {
  padding-left: 0.125rem;
  padding-right: 0.125rem;
}
.px-1 {
  padding-left: 0.25rem;
  padding-right: 0.25rem;
}
.px-1\.5 {
  padding-left: 0.375rem;
  padding-right: 0.375rem;
}
.px-2 {
  padding-left: 0.5rem;
  padding-right: 0.5rem;
}
.px-2\.5 {
  padding-left: 0.625rem;
  padding-right: 0.625rem;
}
.px-3 {
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}
.px-3\.5 {
  padding-left: 0.875rem;
  padding-right: 0.875rem;
}
.px-4 {
  padding-left: 1rem;
  padding-right: 1rem;
}
.px-5 {
  padding-left: 1.25rem;
  padding-right: 1.25rem;
}
.px-6 {
  padding-left: 1.5rem;
  padding-right: 1.5rem;
}
.px-7 {
  padding-left: 1.75rem;
  padding-right: 1.75rem;
}
.py-0 {
  padding-top: 0px;
  padding-bottom: 0px;
}
.py-0\.5 {
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
}
.py-1 {
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
}
.py-1\.5 {
  padding-top: 0.375rem;
  padding-bottom: 0.375rem;
}
.py-10 {
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;
}
.py-12 {
  padding-top: 3rem;
  padding-bottom: 3rem;
}
.py-16 {
  padding-top: 4rem;
  padding-bottom: 4rem;
}
.py-2 {
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}
.py-2\.5 {
  padding-top: 0.625rem;
  padding-bottom: 0.625rem;
}
.py-3 {
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
}
.py-3\.5 {
  padding-top: 0.875rem;
  padding-bottom: 0.875rem;
}
.py-4 {
  padding-top: 1rem;
  padding-bottom: 1rem;
}
.py-5 {
  padding-top: 1.25rem;
  padding-bottom: 1.25rem;
}
.py-6 {
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}
.py-8 {
  padding-top: 2rem;
  padding-bottom: 2rem;
}
.pb-10 {
  padding-bottom: 2.5rem;
}
.pb-2 {
  padding-bottom: 0.5rem;
}
.pb-24 {
  padding-bottom: 6rem;
}
.pb-28 {
  padding-bottom: 7rem;
}
.pb-3 {
  padding-bottom: 0.75rem;
}
.pb-32 {
  padding-bottom: 8rem;
}
.pb-4 {
  padding-bottom: 1rem;
}
.pb-5 {
  padding-bottom: 1.25rem;
}
.pb-6 {
  padding-bottom: 1.5rem;
}
.pb-8 {
  padding-bottom: 2rem;
}
.pb-\[env\(safe-area-inset-bottom\)\] {
  padding-bottom: env(safe-area-inset-bottom);
}
.pl-10 {
  padding-left: 2.5rem;
}
.pl-2 {
  padding-left: 0.5rem;
}
.pl-6 {
  padding-left: 1.5rem;
}
.pl-7 {
  padding-left: 1.75rem;
}
.pl-8 {
  padding-left: 2rem;
}
.pl-9 {
  padding-left: 2.25rem;
}
.pl-\[52px\] {
  padding-left: 52px;
}
.pr-1 {
  padding-right: 0.25rem;
}
.pr-10 {
  padding-right: 2.5rem;
}
.pr-12 {
  padding-right: 3rem;
}
.pr-2 {
  padding-right: 0.5rem;
}
.pr-3 {
  padding-right: 0.75rem;
}
.pr-4 {
  padding-right: 1rem;
}
.pr-8 {
  padding-right: 2rem;
}
.pt-0\.5 {
  padding-top: 0.125rem;
}
.pt-1 {
  padding-top: 0.25rem;
}
.pt-2 {
  padding-top: 0.5rem;
}
.pt-4 {
  padding-top: 1rem;
}
.pt-5 {
  padding-top: 1.25rem;
}
.pt-6 {
  padding-top: 1.5rem;
}
.pt-\[env\(safe-area-inset-top\)\] {
  padding-top: env(safe-area-inset-top);
}
.text-left {
  text-align: left;
}
.text-center {
  text-align: center;
}
.text-right {
  text-align: right;
}
.font-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
.\!text-\[0\.8125rem\] {
  font-size: 0.8125rem !important;
}
.text-2xl {
  font-size: 1.5rem;
  line-height: 2rem;
}
.text-3xl {
  font-size: 1.875rem;
  line-height: 2.25rem;
}
.text-4xl {
  font-size: 2.25rem;
  line-height: 2.5rem;
}
.text-5xl {
  font-size: 3rem;
  line-height: 1;
}
.text-\[0\.625rem\] {
  font-size: 0.625rem;
}
.text-\[0\.6875rem\] {
  font-size: 0.6875rem;
}
.text-\[10px\] {
  font-size: 10px;
}
.text-\[11px\] {
  font-size: 11px;
}
.text-\[15px\] {
  font-size: 15px;
}
.text-\[7px\] {
  font-size: 7px;
}
.text-\[8px\] {
  font-size: 8px;
}
.text-\[9px\] {
  font-size: 9px;
}
.text-base {
  font-size: 1rem;
  line-height: 1.5rem;
}
.text-lg {
  font-size: 1.125rem;
  line-height: 1.75rem;
}
.text-sm {
  font-size: 0.875rem;
  line-height: 1.25rem;
}
.text-xl {
  font-size: 1.25rem;
  line-height: 1.75rem;
}
.text-xs {
  font-size: 0.75rem;
  line-height: 1rem;
}
.\!font-medium {
  font-weight: 500 !important;
}
.font-black {
  font-weight: 900;
}
.font-bold {
  font-weight: 700;
}
.font-extrabold {
  font-weight: 800;
}
.font-medium {
  font-weight: 500;
}
.font-normal {
  font-weight: 400;
}
.font-semibold {
  font-weight: 600;
}
.uppercase {
  text-transform: uppercase;
}
.lowercase {
  text-transform: lowercase;
}
.capitalize {
  text-transform: capitalize;
}
.italic {
  font-style: italic;
}
.tabular-nums {
  --tw-numeric-spacing: tabular-nums;
  font-variant-numeric: var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction);
}
.leading-none {
  line-height: 1;
}
.leading-relaxed {
  line-height: 1.625;
}
.leading-snug {
  line-height: 1.375;
}
.leading-tight {
  line-height: 1.25;
}
.tracking-\[0\.25em\] {
  letter-spacing: 0.25em;
}
.tracking-\[0\.2em\] {
  letter-spacing: 0.2em;
}
.tracking-tight {
  letter-spacing: -0.025em;
}
.tracking-wide {
  letter-spacing: 0.025em;
}
.tracking-wider {
  letter-spacing: 0.05em;
}
.tracking-widest {
  letter-spacing: 0.1em;
}
.text-\[rgb\(120\2c 200\2c 140\)\] {
  --tw-text-opacity: 1;
  color: rgb(120 200 140 / var(--tw-text-opacity, 1));
}
.text-\[rgb\(210\2c 90\2c 80\)\] {
  --tw-text-opacity: 1;
  color: rgb(210 90 80 / var(--tw-text-opacity, 1));
}
.text-\[rgb\(64\2c 140\2c 220\)\] {
  --tw-text-opacity: 1;
  color: rgb(64 140 220 / var(--tw-text-opacity, 1));
}
.text-\[var\(--accent-hex\)\] {
  color: var(--accent-hex);
}
.text-accent {
  color: oklch(var(--accent));
}
.text-accent-foreground {
  color: oklch(var(--accent-foreground));
}
.text-blue-400 {
  --tw-text-opacity: 1;
  color: rgb(96 165 250 / var(--tw-text-opacity, 1));
}
.text-card-foreground {
  color: oklch(var(--card-foreground));
}
.text-cyan-400 {
  --tw-text-opacity: 1;
  color: rgb(34 211 238 / var(--tw-text-opacity, 1));
}
.text-destructive {
  color: oklch(var(--destructive));
}
.text-destructive-foreground {
  color: oklch(var(--destructive-foreground));
}
.text-emerald-400 {
  --tw-text-opacity: 1;
  color: rgb(52 211 153 / var(--tw-text-opacity, 1));
}
.text-foreground {
  color: oklch(var(--foreground));
}
.text-gray-400 {
  --tw-text-opacity: 1;
  color: rgb(156 163 175 / var(--tw-text-opacity, 1));
}
.text-green-400 {
  --tw-text-opacity: 1;
  color: rgb(74 222 128 / var(--tw-text-opacity, 1));
}
.text-green-500 {
  --tw-text-opacity: 1;
  color: rgb(34 197 94 / var(--tw-text-opacity, 1));
}
.text-lime-500 {
  --tw-text-opacity: 1;
  color: rgb(132 204 22 / var(--tw-text-opacity, 1));
}
.text-muted {
  color: oklch(var(--muted));
}
.text-muted-foreground {
  color: oklch(var(--muted-foreground));
}
.text-orange-400 {
  --tw-text-opacity: 1;
  color: rgb(251 146 60 / var(--tw-text-opacity, 1));
}
.text-orange-500 {
  --tw-text-opacity: 1;
  color: rgb(249 115 22 / var(--tw-text-opacity, 1));
}
.text-pink-400 {
  --tw-text-opacity: 1;
  color: rgb(244 114 182 / var(--tw-text-opacity, 1));
}
.text-popover-foreground {
  color: oklch(var(--popover-foreground));
}
.text-primary {
  color: oklch(var(--primary));
}
.text-primary-foreground {
  color: oklch(var(--primary-foreground));
}
.text-purple-400 {
  --tw-text-opacity: 1;
  color: rgb(192 132 252 / var(--tw-text-opacity, 1));
}
.text-red-400 {
  --tw-text-opacity: 1;
  color: rgb(248 113 113 / var(--tw-text-opacity, 1));
}
.text-red-500 {
  --tw-text-opacity: 1;
  color: rgb(239 68 68 / var(--tw-text-opacity, 1));
}
.text-secondary-foreground {
  color: oklch(var(--secondary-foreground));
}
.text-teal-400 {
  --tw-text-opacity: 1;
  color: rgb(45 212 191 / var(--tw-text-opacity, 1));
}
.text-transparent {
  color: transparent;
}
.text-white {
  --tw-text-opacity: 1;
  color: rgb(255 255 255 / var(--tw-text-opacity, 1));
}
.text-yellow-400 {
  --tw-text-opacity: 1;
  color: rgb(250 204 21 / var(--tw-text-opacity, 1));
}
.text-yellow-500 {
  --tw-text-opacity: 1;
  color: rgb(234 179 8 / var(--tw-text-opacity, 1));
}
.underline {
  text-decoration-line: underline;
}
.line-through {
  text-decoration-line: line-through;
}
.underline-offset-2 {
  text-underline-offset: 2px;
}
.underline-offset-4 {
  text-underline-offset: 4px;
}
.opacity-0 {
  opacity: 0;
}
.opacity-100 {
  opacity: 1;
}
.opacity-40 {
  opacity: 0.4;
}
.opacity-50 {
  opacity: 0.5;
}
.opacity-60 {
  opacity: 0.6;
}
.opacity-70 {
  opacity: 0.7;
}
.opacity-75 {
  opacity: 0.75;
}
.opacity-80 {
  opacity: 0.8;
}
.opacity-90 {
  opacity: 0.9;
}
.shadow {
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-2xl {
  --tw-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
  --tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-\[0_0_12px_rgba\(232\2c 99\2c 10\2c 0\.5\)\] {
  --tw-shadow: 0 0 12px rgba(232,99,10,0.5);
  --tw-shadow-colored: 0 0 12px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-\[0_0_14px_rgba\(239\2c 68\2c 68\2c 0\.18\)\] {
  --tw-shadow: 0 0 14px rgba(239,68,68,0.18);
  --tw-shadow-colored: 0 0 14px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-\[0_0_20px_rgba\(var\(--accent-rgb\)\2c 0\.4\)\] {
  --tw-shadow: 0 0 20px rgba(var(--accent-rgb),0.4);
  --tw-shadow-colored: 0 0 20px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-\[0_0_4px_rgba\(250\2c 204\2c 21\2c 0\.6\)\] {
  --tw-shadow: 0 0 4px rgba(250,204,21,0.6);
  --tw-shadow-colored: 0 0 4px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-\[0_0_4px_rgba\(74\2c 222\2c 128\2c 0\.6\)\] {
  --tw-shadow: 0 0 4px rgba(74,222,128,0.6);
  --tw-shadow-colored: 0 0 4px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-lg {
  --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-md {
  --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-none {
  --tw-shadow: 0 0 #0000;
  --tw-shadow-colored: 0 0 #0000;
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.shadow-sm {
  --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}
.\!shadow-\[var\(--neomorph-inset-sm\)\2c 0_0_0_1\.5px_rgba\(var\(--destructive-rgb\)\2c 0\.55\)\] {
  --tw-shadow-color: var(--neomorph-inset-sm),0 0 0 1.5px rgba(var(--destructive-rgb),0.55) !important;
  --tw-shadow: var(--tw-shadow-colored) !important;
}
.outline-none {
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.outline {
  outline-style: solid;
}
.ring {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-0 {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-1 {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-2 {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
.ring-\[rgba\(120\2c 200\2c 140\2c 0\.35\)\] {
  --tw-ring-color: rgba(120,200,140,0.35);
}
.ring-\[rgba\(210\2c 90\2c 80\2c 0\.4\)\] {
  --tw-ring-color: rgba(210,90,80,0.4);
}
.ring-\[rgba\(64\2c 140\2c 220\2c 0\.4\)\] {
  --tw-ring-color: rgba(64,140,220,0.4);
}
.ring-\[rgba\(var\(--accent-rgb\)\2c 0\.4\)\] {
  --tw-ring-color: rgba(var(--accent-rgb),0.4);
}
.ring-accent {
  --tw-ring-color: oklch(var(--accent));
}
.ring-border {
  --tw-ring-color: oklch(var(--border));
}
.ring-emerald-400\/30 {
  --tw-ring-color: rgb(52 211 153 / 0.3);
}
.ring-emerald-500\/20 {
  --tw-ring-color: rgb(16 185 129 / 0.2);
}
.ring-offset-background {
  --tw-ring-offset-color: oklch(var(--background));
}
.blur {
  --tw-blur: blur(8px);
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.drop-shadow {
  --tw-drop-shadow: drop-shadow(0 1px 2px rgb(0 0 0 / 0.1)) drop-shadow(0 1px 1px rgb(0 0 0 / 0.06));
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.drop-shadow-\[0_0_12px_rgba\(var\(--accent-rgb\)\2c 0\.6\)\] {
  --tw-drop-shadow: drop-shadow(0 0 12px rgba(var(--accent-rgb),0.6));
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.drop-shadow-\[0_1px_2px_rgba\(0\2c 0\2c 0\2c 0\.6\)\] {
  --tw-drop-shadow: drop-shadow(0 1px 2px rgba(0,0,0,0.6));
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.filter {
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.backdrop-blur {
  --tw-backdrop-blur: blur(8px);
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.backdrop-blur-md {
  --tw-backdrop-blur: blur(12px);
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.backdrop-blur-sm {
  --tw-backdrop-blur: blur(4px);
  backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
}
.transition {
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-\[color\2c box-shadow\] {
  transition-property: color,box-shadow;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-all {
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-colors {
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-opacity {
  transition-property: opacity;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.transition-transform {
  transition-property: transform;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
}
.duration-150 {
  transition-duration: 150ms;
}
.duration-200 {
  transition-duration: 200ms;
}
.duration-300 {
  transition-duration: 300ms;
}
.duration-500 {
  transition-duration: 500ms;
}
.ease-in-out {
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.ease-out {
  transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.will-change-scroll {
  will-change: scroll-position;
}
.will-change-transform {
  will-change: transform;
}
@keyframes enter {

  from {
    opacity: var(--tw-enter-opacity, 1);
    transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0));
  }
}
@keyframes exit {

  to {
    opacity: var(--tw-exit-opacity, 1);
    transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0) scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0));
  }
}
.animate-in {
  animation-name: enter;
  animation-duration: 150ms;
  --tw-enter-opacity: initial;
  --tw-enter-scale: initial;
  --tw-enter-rotate: initial;
  --tw-enter-translate-x: initial;
  --tw-enter-translate-y: initial;
}
.fade-in {
  --tw-enter-opacity: 0;
}
.fade-in-0 {
  --tw-enter-opacity: 0;
}
.fade-in-50 {
  --tw-enter-opacity: 0.5;
}
.zoom-in-95 {
  --tw-enter-scale: .95;
}
.slide-in-from-bottom {
  --tw-enter-translate-y: 100%;
}
.slide-in-from-bottom-2 {
  --tw-enter-translate-y: 0.5rem;
}
.duration-150 {
  animation-duration: 150ms;
}
.duration-200 {
  animation-duration: 200ms;
}
.duration-300 {
  animation-duration: 300ms;
}
.duration-500 {
  animation-duration: 500ms;
}
.ease-in-out {
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
.ease-out {
  animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.running {
  animation-play-state: running;
}
.paused {
  animation-play-state: paused;
}
/* Neumorphic Raised Elements — no will-change on static cards to reduce GPU overhead */
.neomorph {
    box-shadow: var(--neomorph-shadow), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.neomorph-sm {
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.neomorph-lg {
    box-shadow: var(--neomorph-shadow-lg), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.neomorph-xl {
    box-shadow: var(--neomorph-shadow-xl);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
/* Neumorphic Inset Elements — no box-shadow transition: the box-shadow IS
     the visible background/border of inputs in this design. A 200ms transition
      re-interpolates on every keystroke re-render, causing the input to briefly
      disappear. Keep the shadow static so the inset look stays visible. */
.neomorph-inset {
    box-shadow: var(--neomorph-inset);
  }
.neomorph-inset-sm {
    box-shadow: var(--neomorph-inset-sm);
  }
/* ═══════════════════════════════════════════════════════════════════════════
     WEEKLY CHALLENGE — compacted card utilities (Phase: Compacted Weekly Challenge)
     Additive only — reuses --accent-hex / --accent-rgb / --muted / --foreground
     tokens. The ring well is a dedicated engraved treatment (deeper inset than
     .neomorph-inset-sm) so the ProgressRing SVG appears sunk into the card.
     State color is driven by --wq-state-color / --wq-state-rgb on the card root;
     state 1 = orange (default), state 2 = amber, state 3 = soft green. All three
     states share the same well + glow rules — only the CSS vars change.
     ═══════════════════════════════════════════════════════════════════════════ */
/* Card shell — compact horizontal layout. Tight padding, rounded-2xl, raised
     neumorphic-sm surface. Whole card is tappable (state 1 & 2) → opens Drawer;
     state 3 adds .wq-card--static to disable interaction. */
.wq-card {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.75rem 0.875rem;
    border-radius: 1rem;
    background-color: oklch(var(--card));
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 200ms
      cubic-bezier(0.4, 0, 0.2, 1);
    cursor: pointer;
    contain: layout style;
  }
.wq-card:active {
    transform: scale(0.99) translateZ(0);
    box-shadow: var(--neomorph-pressed);
  }
/* State 3 (recovery) — non-interactive, no tap action, default cursor. */
.wq-card--static {
    cursor: default;
  }
.wq-card--static:active {
    transform: none;
    box-shadow: var(--neomorph-shadow-sm);
  }
/* ═══════════════════════════════════════════════════════════════════════════
     HOME WELCOME BLOCK — new-user hero utilities (wb- prefix)
     Additive only — reuses --accent-hex / --accent-rgb / --card / --foreground /
     --muted-foreground tokens. The welcome block is the ONLY thing shown to a
     new user (0 workouts) before the first completed workout, so it is kept
     restrained and stable: an engraved neumorphic hero card with a single
     orange-accent CTA. No stats, no day-dots, no streak — just a warm, clear
     invitation to start. Honors prefers-reduced-motion via the global rule.
     ═══════════════════════════════════════════════════════════════════════════ */
/* Welcome hero card — engraved recess hosting the whole welcome block.
     Mirrors --op-card-well depth language; card background so it reads as a
     sculpted surface on the page background. */
.wb-card {
    box-shadow: var(--wb-card-well);
    border-radius: 1.25rem;
    background-color: oklch(var(--card));
    padding: 1.5rem 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }
/* Leading icon well — engraved circular recess hosting the start icon.
     Orange glow makes it the visual anchor of the welcome block. */
.wb-icon {
    box-shadow: var(--wb-icon-well), var(--wb-icon-glow);
    border-radius: 9999px;
    width: 3.5rem;
    height: 3.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--accent-hex);
    background: rgba(var(--accent-rgb), 0.14);
  }
/* Eyebrow chip — small uppercase label above the headline. */
.wb-eyebrow {
    box-shadow: var(--wb-eyebrow-well);
    border-radius: 9999px;
    padding: 0.25rem 0.625rem;
    font-family: var(--font-display);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: oklch(var(--muted-foreground));
    align-self: flex-start;
  }
/* Headline — Space Grotesk display, bold, tight tracking. */
.wb-title {
    font-family: var(--font-display);
    font-size: 1.5rem;
    line-height: 1.15;
    font-weight: 700;
    letter-spacing: -0.02em;
    color: oklch(var(--foreground));
  }
/* Subtext — General Sans body, muted, max-width for comfortable reading. */
.wb-subtext {
    font-family: var(--font-body);
    font-size: 0.9375rem;
    line-height: 1.55;
    color: oklch(var(--muted-foreground));
    max-width: 34ch;
  }
/* Primary CTA — accent gradient + soft breathing orange glow. The single
     primary action for a new user; 44px+ tap target. */
.wb-cta {
    background: linear-gradient(135deg, var(--accent-hex), var(--accent-dim));
    color: var(--accent-foreground);
    border: none;
    border-radius: 0.875rem;
    padding: 0.875rem 1.5rem;
    font-family: var(--font-display);
    font-size: 0.9375rem;
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--wb-cta-glow);
    animation: wb-cta-pulse 3.2s ease-in-out infinite;
    transition: transform 150ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 200ms
      cubic-bezier(0.4, 0, 0.2, 1);
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }
.wb-cta:hover {
    transform: scale(1.02);
  }
.wb-cta:active {
    transform: scale(0.98);
  }
.wb-cta:focus-visible {
    outline: 2px solid oklch(var(--ring));
    outline-offset: 2px;
  }
@media (prefers-reduced-motion: reduce) {
    .wb-cta {
      animation: none !important;
    }
  }
/* Breathing orange glow on the welcome-block primary CTA. Mirrors the
     tailwind.config.js wb-cta-pulse keyframe (reads --accent-rgb). Redefined
     here so the animation is emitted into the built CSS even though no
     animate-wb-cta-pulse utility is used. */
@keyframes wb-cta-pulse {
    0%,
    100% {
      box-shadow: 0 0 6px rgba(var(--accent-rgb), 0.45), 0 0 14px
        rgba(var(--accent-rgb), 0.22);
    }
    50% {
      box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.65), 0 0 20px
        rgba(var(--accent-rgb), 0.36);
    }
  }
/* Ring well — circular recessed area hosting the ProgressRing SVG.
     Deeper inset than .neomorph-inset-sm: 5px dark inner shadow + 5px subtle
     white highlight + 1px hairline rim = engraved look. Sized to wrap an
     88px ring with ~6px breathing room (100px well). */
.blueprint-engraved-field {
    box-shadow: var(--neomorph-inset-sm);
    border-radius: 0.75rem;
    padding: 14px 18px;
    width: 100%;
    background: transparent;
    transition: box-shadow 0.2s ease;
  }
.blueprint-engraved-field:focus-within,
  .blueprint-engraved-field input:focus,
  .blueprint-engraved-field textarea:focus {
    box-shadow: var(--neomorph-inset-sm), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.55), 0 0 12px rgba(var(--accent-rgb), 0.18);
  }
.blueprint-engraved-field input,
  .blueprint-engraved-field textarea {
    background: transparent;
    border: none;
    outline: none;
    color: inherit;
    width: 100%;
  }
@keyframes blueprint-save-pulse {
    0%,
    100% {
      box-shadow: var(--neomorph-shadow), 0 0 18px rgba(var(--accent-rgb), 0.35);
    }
    50% {
      box-shadow: var(--neomorph-shadow), 0 0 24px rgba(var(--accent-rgb), 0.6);
    }
  }
.blueprint-add-exercise svg,
  .blueprint-add-exercise .lucide {
    color: var(--accent-hex);
  }
.blueprint-exercises-well {
    box-shadow: var(--blueprint-exercises-well);
    border-radius: 0.75rem;
    padding: 20px;
    background: transparent;
  }
/* ═══════════════════════════════════════════════════════════════════════════
     BLUEPRINT BUILDER — FASE 2 SURFACES (bp2- prefix)
     Additive only — does NOT modify any existing .blueprint-* Fase 1 classes.
     Reuses shadow patterns from .blueprint-engraved-field (inset + orange focus
     glow) and .neomorph-inset / .neomorph-button. All orange accents use
     --accent-hex / --accent-rgb tokens (theme-agnostic). No new @keyframes —
     reuses blueprint-save-pulse where a pulse is needed.
     ═══════════════════════════════════════════════════════════════════════════ */
/* Search bar — neomorph-inset engraved field with orange focus glow.
     Mirrors .blueprint-engraved-field pattern. Full width, rounded, padded
     for a leading icon + text input. The wrapper carries the inset shadow;
     the inner input is transparent/borderless. */
.bp2-search-input {
    box-shadow: var(--neomorph-inset-sm);
    border-radius: 0.75rem;
    padding: 2px 10px;
    width: 100%;
    background: transparent;
    transition: box-shadow 0.2s ease;
  }
.bp2-search-input:focus-within,
  .bp2-search-input input:focus,
  .bp2-search-input textarea:focus {
    /* INSET accent ring — traces the same border-box as the inset shadow so the
       ring stays symmetric (no right+bottom shift). The outset glow stays
       outside the box and does not affect the ring geometry. */
    box-shadow: var(--neomorph-inset-sm), inset 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.55), 0 0 12px rgba(var(--accent-rgb), 0.18);
  }
.bp2-search-input input,
  .bp2-search-input textarea {
    background: transparent;
    border: none;
    outline: none;
    color: inherit;
    width: 100%;
  }
/* Muscle-group filter chip — neomorph-button base, small rounded pill.
     Quiet raised surface; tap to toggle. */
.bp2-chip {
    box-shadow: var(--neomorph-shadow);
    border-radius: 9999px;
    padding: 6px 14px;
    font-size: 0.875rem;
    line-height: 1rem;
    background-color: oklch(var(--card));
    color: oklch(var(--foreground));
    transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
      cubic-bezier(0.4, 0, 0.2, 1), background-color 150ms ease;
    will-change: transform;
    contain: layout style;
  }
.bp2-chip:hover:not(:disabled) {
    box-shadow: var(--neomorph-hover);
    transform: scale(1.02) translateZ(0);
  }
.bp2-chip:active:not(:disabled) {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.98) translateZ(0);
  }
.bp2-chip:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
  }
/* Active chip — orange accent fill + glow using --accent-hex / --accent-rgb.
     Overrides the quiet raised surface with a warm filled pill. */
.bp2-chip--active {
    background-color: var(--accent-hex);
    color: #fff;
    box-shadow: var(--neomorph-shadow), 0 0 14px rgba(var(--accent-rgb), 0.45);
  }
.bp2-chip--active:hover:not(:disabled) {
    background-color: var(--accent-hex);
    box-shadow: var(--neomorph-hover), 0 0 18px rgba(var(--accent-rgb), 0.6);
  }
/* Collapsible category panel — smooth slide-down via the
     grid-template-rows: 0fr → 1fr trick. The outer .bp2-collapsible element
     animates its grid row height; the inner .bp2-collapsible__inner div carries
     overflow-hidden so chips don't bleed out while collapsing. Opacity fades
     the inner content for a softer reveal. Honors prefers-reduced-motion via
     the global rule at the bottom of this file. */
.bp2-collapsible {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    transition: grid-template-rows 220ms cubic-bezier(0.4, 0, 0.2, 1), opacity
      200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.bp2-collapsible[data-state="open"] {
    grid-template-rows: 1fr;
    opacity: 1;
  }
.bp2-collapsible__inner {
    overflow: hidden;
    min-height: 0;
  }
/* Top-3 recent suggestion card — compact neumorph raised, tappable.
     Tight padding, rounded, touch-manipulation for low-latency taps. */
/* Starter suggestion card (Push/Pull/Leg Day) — larger neumorph raised
     with hover orange glow. More generous padding than .bp2-recent-card. */
/* Mini-illustration container for empty state — centered, subtle opacity
     so the illustration reads as a quiet decorative hint, not a focal point. */
/* 'Start from scratch' button — neomorph-button base with an orange accent
     outline/border. Quiet raised surface with a warm rim to signal the primary
     creation path. */
/* Sticky bottom mini-preview bar — neomorph-inset, tappable, rounded top.
     Sits pinned to the bottom of the viewport; opens the full preview modal. */
/* Compact exercise row inside the mini-preview — flex row, name + sets x reps.
     Truncates long exercise names so the bar stays a single line. */
/* ════════════════════════════════════════════════════════════════════════
     bp2-type-badge — per-exercise type pill (strength / cardio / mobility)
     Inline-flex pill with small padding + rounded-full + subtle background
     tint. Strength uses the user's accent color (var(--accent-hex) /
     var(--accent-rgb)) so it follows the instellingen accent keuze — NO
     hardcoded orange #E8630A. Cardio gets a rose/red tint (#ef4444), mobility
     gets an emerald/green tint (#10b981). The icon is 12px currentColor; the
     label is small uppercase letter-spaced text. Consistent with the existing
     neumorphic pill language (bp2-chip) but smaller and type-tinted.
     ════════════════════════════════════════════════════════════════════════ */
/* Strength — user accent color. Reads --accent-hex for the solid text/icon
     color and --accent-rgb for the subtle 12% background tint. This means the
     badge follows the instellingen accent keuze (blauw, oranje, etc.) instead
     of forcing orange #E8630A. */
/* Cardio — rose/red tint. Distinct from strength accent and from
     --destructive so it reads as an exercise-type indicator, not an error. */
/* Mobility — emerald/green tint. Distinct from strength and cardio so the
     three exercise types are visually separable at a glance. */
/* 12px SVG icon — inherits currentColor from the badge modifier. */
/* Small uppercase letter-spaced label — sits next to the icon. */
/* Full-screen modal overlay — dark scrim with a subtle orange tint and
     backdrop-blur. Sits above all content; clicking it dismisses the modal. */
/* The preview modal card — neumorph raised, rounded-2xl, max-height 80vh,
     scrollable. Slides up from the bottom on mobile, centers on desktop. */
@keyframes bp2-modal-rise {
    from {
      transform: translateY(24px);
      opacity: 0;
    }
    to {
      transform: translateY(0);
      opacity: 1;
    }
  }
@media (min-width: 640px) {
    .bp2-preview-modal-overlay {
      align-items: center;
      padding: 1rem;
    }
    .bp2-preview-modal {
      animation: bp2-modal-fade 200ms cubic-bezier(0.16, 1, 0.3, 1);
    }
    @keyframes bp2-modal-fade {
      from {
        opacity: 0;
        transform: scale(0.98);
      }
      to {
        opacity: 1;
        transform: scale(1);
      }
    }
  }
.wq-ring-well {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100px;
    height: 100px;
    border-radius: 9999px;
    background-color: oklch(var(--background));
    box-shadow: var(--wq-ring-well);
    flex-shrink: 0;
  }
/* Soft glow on the active progress arc — applied to the SVG element (or the
     arc path) so the orange (or amber/green) stroke carries a warm halo.
     Reads --wq-state-color / --wq-state-rgb so all 3 states share one rule. */
.wq-arc-glow {
    filter: drop-shadow(0 0 5px rgba(var(--wq-state-rgb), 0.55))
      drop-shadow(0 0 12px rgba(var(--wq-state-rgb), 0.22));
  }
/* Text column — tight hierarchy. Header on one line, sessions prominent,
     subtext 1 line, badge top-right. */
.wq-text {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    flex: 1 1 auto;
    min-width: 0;
  }
/* Header — label stacks above the quest name so the name gets the full
     text-column width instead of being squeezed into a narrow column beside
     the uppercase "Weekly Challenge" label. Wrapping is allowed so long
     quest titles render completely on both desktop and mobile. */
.wq-header {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
    line-height: 1.15;
  }
.wq-header__label {
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: oklch(var(--muted-foreground));
  }
/* Quest name — renders fully without line-clamping or overflow truncation.
     min-height keeps the card footprint stable for short single-line names
     while allowing long titles to wrap onto additional lines as needed. */
.wq-header__name {
    font-family: var(--font-display);
    font-size: 0.9375rem;
    font-weight: 600;
    color: oklch(var(--foreground));
    line-height: 1.2;
    min-height: calc(1.2em * 1);
    word-break: break-word;
    overflow-wrap: anywhere;
  }
.wq-sessions {
    font-family: var(--font-display);
    font-size: 1.0625rem;
    font-weight: 700;
    color: oklch(var(--foreground));
    line-height: 1.2;
  }
/* Rest-days integrated — small inline icon + label, muted, sits on the same
     line as the sessions count (flex row) so it never becomes a 4th text line. */
.wq-rest {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: 0.5rem;
    color: oklch(var(--muted-foreground));
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 500;
    vertical-align: middle;
  }
.wq-rest__icon {
    width: 12px;
    height: 12px;
    flex-shrink: 0;
    opacity: 0.8;
  }
/* Subtext — renders fully without line-clamping or overflow truncation so
     long interpolated {muscleGroup} and {description} values from the
     focusDetailExplanation render completely on both desktop and mobile.
     min-height keeps the card footprint stable for short single-line
     subtext while allowing long descriptions to wrap onto additional lines. */
.wq-subtext {
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 400;
    color: oklch(var(--muted-foreground));
    line-height: 1.3;
    min-height: calc(1.3em * 1);
    word-break: break-word;
    overflow-wrap: anywhere;
  }
/* "Why this challenge" callout — accent-tinted inset well that surfaces the
     backend-provided reason for the weekly challenge. Sits below the subtext
     row and uses the neumorphic inset language so it reads as a distinct
     explanation block rather than plain body copy. */
.wq-reason {
    margin-top: 0.5rem;
    padding: 0.5rem 0.625rem;
    border-radius: 0.75rem;
    background-color: rgba(var(--accent-rgb), 0.1);
    color: oklch(var(--foreground));
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 500;
    line-height: 1.35;
    word-break: break-word;
    overflow-wrap: anywhere;
  }
/* Reward badge — pill, accent-tinted bg + accent text, top-right corner.
     Uses --wq-state-color so state 2/3 badges match the ring tint. */
.wq-reward {
    position: absolute;
    top: 0.5rem;
    right: 0.625rem;
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0.1875rem 0.5rem;
    border-radius: 9999px;
    background-color: rgba(var(--wq-state-rgb), 0.14);
    color: var(--wq-state-color);
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    line-height: 1;
  }
/* State color overrides — set --wq-state-color / --wq-state-rgb on the card
     root. State 1 inherits the defaults (orange). */
.wq-card--state-2 {
    --wq-state-color: oklch(0.82 0.13 80);
    --wq-state-rgb: 232, 178, 60;
  }
.wq-card--state-3 {
    --wq-state-color: oklch(0.78 0.1 145);
    --wq-state-rgb: 120, 200, 140;
  }
/* ═══════════════════════════════════════════════════════════════════════════
     FASE 1 STATS — Monthly Calendar + Goal ring + Week bars + Insight card
     Additive utilities (Phase: Fase 1 Stats tab upgrade). Reuses existing
     --accent-hex / --accent-rgb / --neomorph-shadow / --neomorph-inset-sm
     tokens plus the new --mw-* tokens defined above. Mirrors the .wq-ring-well
     engraved pattern for both calendar tiles and the monthly goal ring well so
     the Stats tab shares the same sculpted-recess language as the Weekly Challenge
     card. All classes are additive — no existing classes or tokens modified.
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Monthly calendar grid ─────────────────────────────────────────────────
     7-column grid for the days of the week. Tight gap (0.375rem) so the
     engraved tiles sit close together and read as a single sculpted surface. */
.mw-grid {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 0.375rem;
  }
/* ─── Base engraved day tile ────────────────────────────────────────────────
     Square (aspect-square) rounded-lg tile with the --mw-tile-well engraved
     inset. Flex-centered so the day number sits in the visual middle of the
     recess. Background = bg-background so the tile reads as a hole sunk into
     the card surface (same language as .wq-ring-well). */
.mw-tile {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1 / 1;
    border-radius: 0.5rem;
    background-color: oklch(var(--background));
    box-shadow: var(--mw-tile-well);
    color: oklch(var(--muted-foreground));
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    -webkit-user-select: none;
       -moz-user-select: none;
            user-select: none;
  }
/* ─── Trained day ───────────────────────────────────────────────────────────
     Orange glow halo + accent-colored day number + a small checkmark icon
     top-right. The glow layers ON TOP of the engraved well (box-shadow can
     hold multiple layers — well + glow). Reads as "this day is lit". */
.mw-tile--trained {
    color: var(--accent-hex);
    font-weight: 700;
    box-shadow: var(--mw-tile-well), var(--mw-tile-trained-glow);
  }
/* ─── Today ─────────────────────────────────────────────────────────────────
     Thin accent ring around the tile (not a glow) so today stays distinct
     from trained days. Ring layers on top of the engraved well. */
.mw-tile--today {
    box-shadow: var(--mw-tile-well), var(--mw-tile-today-ring);
  }
/* Today + trained combo: well + glow + ring all layered so today's trained
     day reads as the most prominent tile on the grid. */
.mw-tile--today.mw-tile--trained {
    box-shadow: var(--mw-tile-well), var(--mw-tile-trained-glow),
      var(--mw-tile-today-ring);
  }
/* ─── Rest day (non-trained in-month) ──────────────────────────────────────
     Subtle lighter inset (--mw-tile-rest) so rest days read as quieter empty
     engraved tiles — still part of the month, just not trained. Muted day
     number, no glow, no checkmark. */
.mw-tile--rest {
    box-shadow: var(--mw-tile-rest);
  }
/* ─── Out-of-month day ──────────────────────────────────────────────────────
     Dimmed to 30% opacity, no interaction, no engraved well (flat) so it
     recedes visually behind the in-month tiles. Pointer-events disabled so
     taps pass through. */
.mw-tile--out {
    opacity: 0.3;
    box-shadow: none;
    background-color: transparent;
    pointer-events: none;
  }
/* ─── Trained-day checkmark indicator ───────────────────────────────────────
     Small checkmark icon top-right of a trained tile. Accent color, tiny
     (10px), absolute positioned so it doesn't shift the centered day number. */
.mw-tile-check {
    position: absolute;
    top: 0.1875rem;
    right: 0.1875rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 10px;
    height: 10px;
    color: var(--accent-hex);
    pointer-events: none;
  }
.mw-tile-check svg {
    width: 10px;
    height: 10px;
  }
/* ─── Monthly Goal ring well ────────────────────────────────────────────────
     Mirrors .wq-ring-well exactly: 100px circular recess with the --mw-ring-well
     engraved inset (5px deep + hairline rim). Hosts a ProgressRing SVG
     (size=88, strokeWidth=8) centered inside. Background = bg-background so the
     ring reads as sunk into the card surface. */
.mw-ring-well {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100px;
    height: 100px;
    border-radius: 9999px;
    background-color: oklch(var(--background));
    box-shadow: var(--mw-ring-well);
    flex-shrink: 0;
  }
/* ─── Monthly goal arc glow ─────────────────────────────────────────────────
     Soft warm drop-shadow halo on the progress arc SVG. Same alpha as
     .wq-arc-glow so the monthly ring breathes the same way as the weekly
     challenge ring. Applied to the SVG element (or arc path). */
.mw-ring-glow {
    filter: drop-shadow(0 0 5px rgba(var(--accent-rgb), 0.55))
      drop-shadow(0 0 12px rgba(var(--accent-rgb), 0.22));
  }
/* ─── Monthly goal centered text ────────────────────────────────────────────
     Centered X/Y fraction overlaid on the ring well. Display font, the
     fraction in accent color, a small muted label underneath. Absolute
     positioned so it sits dead-center over the ProgressRing. */
.mw-ring-text {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.0625rem;
    pointer-events: none;
    text-align: center;
  }
.mw-ring-text__fraction {
    font-family: var(--font-display);
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--accent-hex);
    line-height: 1.1;
    letter-spacing: 0.01em;
  }
.mw-ring-text__label {
    font-family: var(--font-body);
    font-size: 0.5625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: oklch(var(--muted-foreground));
    line-height: 1;
  }
/* ─── Compact week breakdown row ────────────────────────────────────────────
     Horizontal flex row hosting 4 mini-bars (W1-W4). gap-2 (0.5rem) so the
     mini-bars have breathing room. */
.mw-week-row {
    display: flex;
    align-items: stretch;
    gap: 0.5rem;
    width: 100%;
  }
/* ─── Mini-bar container (one per week) ─────────────────────────────────────
     flex-1 so 4 mini-bars share the row equally. flex-col, items-center so
     the label sits above the bar and the value below. */
.mw-week-mini {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    flex: 1 1 0;
    min-width: 0;
  }
/* ─── Week label (W1-W4) ────────────────────────────────────────────────────
     Tiny uppercase letter-spaced muted label above each mini-bar. */
.mw-week-label {
    font-family: var(--font-body);
    font-size: 0.5625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: oklch(var(--muted-foreground));
    line-height: 1;
  }
/* ─── Progress bar track ────────────────────────────────────────────────────
     h-1.5 (6px) rounded-full inset track. Neomorph-inset-sm so the fill
     appears to sit inside a sculpted groove. Background = bg-background. */
.mw-week-bar {
    position: relative;
    width: 100%;
    height: 6px;
    border-radius: 9999px;
    background-color: oklch(var(--background));
    box-shadow: var(--neomorph-inset-sm);
    overflow: hidden;
  }
/* ─── Progress bar fill ─────────────────────────────────────────────────────
     Accent-colored fill with a soft orange glow. Width driven inline by the
     component. Sits inside the inset track so it reads as a lit bar in a
     groove. */
.mw-week-bar-fill {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    border-radius: 9999px;
    background-color: var(--accent-hex);
    box-shadow: 0 0 4px rgba(var(--accent-rgb), 0.55);
    transition: width 300ms cubic-bezier(0.4, 0, 0.2, 1);
  }
/* ─── Compact week value ────────────────────────────────────────────────────
     Small value text below each mini-bar — "gehaald/doel" or remaining count.
     Muted, tiny, centered. */
.mw-week-value {
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: 500;
    color: oklch(var(--muted-foreground));
    line-height: 1;
    text-align: center;
  }
/* ─── Insight card ──────────────────────────────────────────────────────────
     Neumorphic raised card (rounded-xl) hosting the rule-based insight. Thin
     orange left border (3px accent) + a small accent icon so the insight
     reads as a distinct, highlighted callout. Padding matches .card-compact. */
.mw-insight {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    padding: 0.75rem 0.875rem 0.75rem 0.875rem;
    border-radius: 0.75rem;
    background-color: oklch(var(--card));
    box-shadow: var(--neomorph-shadow-sm);
    border-left: 3px solid var(--accent-hex);
    overflow: hidden;
  }
/* Insight accent icon — small square (28px) accent-tinted background with
     accent-colored icon. Sits at the top-left next to the left border. */
.mw-insight__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background-color: rgba(var(--accent-rgb), 0.14);
    color: var(--accent-hex);
    flex-shrink: 0;
  }
/* Insight text column — header + body. Tight gap. */
.mw-insight__text {
    display: flex;
    flex-direction: column;
    gap: 0.1875rem;
    flex: 1 1 auto;
    min-width: 0;
  }
.mw-insight__header {
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 600;
    color: oklch(var(--foreground));
    line-height: 1.2;
  }
.mw-insight__body {
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 400;
    color: oklch(var(--muted-foreground));
    line-height: 1.35;
  }
/* ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Solid field container (ExerciseCard redesign) ───────────────────
     Replaces the neumorphic-inset look for exercise set inputs. Solid dark
     fill, 1px border, fully-rounded pill (border-radius:9999px), ~44px
     height, centered value. NO inset shadows, NO transition/animation on the
     container. On focus ONLY the border color changes to orange (#E8630A) —
     nothing else changes. Pill shape matches the landing-page card reference
     style. */
.solid-field {
    background-color: #232327;
    border: 1px solid #38383c;
    border-radius: 9999px;
    height: 44px;
    color: oklch(var(--foreground));
    text-align: center;
    box-shadow: none;
    transition: none;
  }
.solid-field:focus {
    border-color: var(--accent-hex);
    outline: none;
    /* Subtle INSET accent ring follows the 9999px pill cleanly so the focus
       state is symmetric and does not clip on the right cap. Replaces the
       Tailwind focus-visible:ring-2 (outset ring with default offset) that
       created an asymmetric gap and right-edge clipping. */
    box-shadow: inset 0 0 0 1.5px rgba(var(--accent-rgb), 0.45);
  }
.solid-field:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
.solid-field::-moz-placeholder {
    color: oklch(var(--muted-foreground) / 0.5);
    opacity: 1;
  }
.solid-field::placeholder {
    color: oklch(var(--muted-foreground) / 0.5);
    opacity: 1;
  }
/* Variant for taller cardio inputs (matches the previous h-12 footprint) */
/* ─── Solid checkmark (ExerciseCard redesign) ────────────────────────
     Round, default = gray with a border (not filled); completed = filled
     with full-orange background and white check icon. NO neumorphic
     shadows. Only the color/border changes — no layout-affecting transition
     on the container (uses color/border-color transition only). */
/* ─── Muted field labels (ExerciseCard redesign) ─────────────────────
     Small uppercase letter-spaced muted-grey labels above each set input
     field (SET / KG / REPS / DURATION / DISTANCE). Matches the landing-page
     card reference style. */
/* ─── Ghost "+ Add Set" button (ExerciseCard redesign) ────────────────
     Subtle ghost-style button: transparent background, muted border, muted
     text. On hover the border + text shift to the orange accent. No
     neumorphic shadow — keeps the button quiet per the landing reference. */
/* ─── Light-theme overrides for solid-field / solid-field-lg / solid-check ──
     The base rules above use hardcoded dark-mode colors (#232327 fill,
     #38383c/#4a4a50 border). In the light theme these stay dark, making the
     dark foreground text unreadable. These :root:not(.dark) overrides swap
     the fill to #f0edea and the border to #c8c4be — matching the existing
     .modal-exercise-search light-mode pattern (regels 933-943). Focus state
     keeps --accent-hex (orange) which works in both themes. The .dark theme
     is NOT touched — base rules keep applying unchanged in dark mode. */
:root:not(.dark) .solid-field,
  :root:not(.dark) .solid-field-lg {
    background-color: #f0edea !important;
    border-color: #c8c4be !important;
  }
:root:not(.dark) .solid-field::-moz-placeholder, :root:not(.dark) .solid-field-lg::-moz-placeholder {
    /* oklch(var(--muted-foreground) / 0.5) is too light on #f0edea — use a
       darker gray for sufficient contrast in light mode. */
    color: #6b6b6b !important;
    opacity: 1 !important;
  }
:root:not(.dark) .solid-field::placeholder,
  :root:not(.dark) .solid-field-lg::placeholder {
    /* oklch(var(--muted-foreground) / 0.5) is too light on #f0edea — use a
       darker gray for sufficient contrast in light mode. */
    color: #6b6b6b !important;
    opacity: 1 !important;
  }
/* Light-theme completed check = same orange fill + white check as dark
     mode (per requirement: oranje gevulde cirkel met witte check in both
     themes). */
/* ═══════════════════════════════════════════════════════════════════════════
     EXERCISE CARD REDESIGN — landing-page reference style
     Compact, clean, non-bulky exercise cards. Header sits ABOVE the card (slim
     row, no card background); the card hosts a single header-row set table with
     pill-shaped borderless inputs and orange-filled checkmarks. An inline rest
     timer strip (thin orange progress bar) appears under a completed set row.
     A ghost "+ Add Set" button (no dashed border) closes the card.
     All classes reuse existing OKLCH tokens (--background, --card, --foreground,
     --muted, --muted-foreground, --border, --accent, --accent-hex, --accent-rgb)
     and the --font-display / --font-body variables. Both :root (light) and .dark
     themes are handled via inherited variables plus explicit light overrides at
     the bottom of this block. Existing .solid-field / .solid-check /
     .solid-add-set classes are NOT touched — these classes are additive.
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Header row above the card ─────────────────────────────────────────────
     Slim ~40px row, no card background, no shadow. Icon + exercise name on the
     left, timer pill + delete button on the right. Subtle spacing only. */
.ex-card-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 40px;
    padding: 0 0.25rem 0.375rem;
    background: transparent;
    box-shadow: none;
  }
.ex-card-header__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background-color: oklch(var(--muted));
    color: oklch(var(--muted-foreground));
    flex-shrink: 0;
  }
.ex-card-header__name {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.9375rem;
    line-height: 1.2;
    color: oklch(var(--foreground));
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
.ex-card-header__actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    flex-shrink: 0;
  }
/* ─── Collapsible action buttons container ─────────────────────────────────
     Wraps the rest-stepper (timer pill), RPE (pulse) button, and clock (timer
     mode) button. Slides in from right-to-left when the header expands, and
     collapses back when it contracts. Driven by the local isExpanded state in
     ExerciseCard — only the expand button toggles it.

     Animation strategy: animate max-width + opacity + margin-left. width:auto
     is not animatable, so we use max-width (0 → 240px, enough for the three
     28px buttons + gaps + the rest-stepper label). overflow:hidden clips the
     buttons during the slide. pointer-events disabled while collapsed so the
     hidden buttons can't be tapped accidentally. */
.ex-card-header__collapsible-actions {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    overflow: hidden;
    max-width: 0;
    margin-left: 0;
    opacity: 0;
    pointer-events: none;
    transition: max-width 250ms ease-in-out, opacity 250ms ease-in-out,
      margin-left 250ms ease-in-out;
  }
.ex-card-header__collapsible-actions.is-open {
    max-width: 240px;
    opacity: 1;
    pointer-events: auto;
  }
/* ─── Expand / collapse button ─────────────────────────────────────────────
     28px neomorph pill button matching .ex-card-header__rpe-btn base styling
     (same size, border-radius, background, box-shadow, hover/active states).
     Sits directly LEFT of the trash button. Shows ChevronLeft when collapsed
     (pointing toward the name) and ChevronRight when expanded. */
.ex-card-header__expand-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 9999px;
    background-color: oklch(var(--muted));
    color: oklch(var(--muted-foreground));
    border: none;
    box-shadow: var(--neomorph-inset-sm);
    transition: color 150ms ease, background-color 150ms ease, box-shadow 150ms
      ease;
    cursor: pointer;
  }
.ex-card-header__expand-btn:hover {
    color: oklch(var(--accent));
    background-color: rgba(var(--accent-rgb), 0.1);
  }
.ex-card-header__expand-btn:focus-visible {
    outline: none;
    box-shadow: var(--neomorph-inset-sm), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.6);
  }
/* Timer pill button — small, quiet, accent on hover/active only */
.ex-card-header__timer-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    height: 28px;
    padding: 0 0.625rem;
    border-radius: 9999px;
    background-color: oklch(var(--muted));
    color: oklch(var(--muted-foreground));
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 600;
    border: none;
    box-shadow: none;
    transition: color 150ms ease, background-color 150ms ease;
  }
.ex-card-header__timer-btn:hover {
    color: oklch(var(--accent));
    background-color: rgba(var(--accent-rgb), 0.1);
  }
.ex-card-header__timer-btn.is-active {
    background-color: var(--accent-hex);
    color: #ffffff;
  }
/* Delete button — small ghost icon button */
.ex-card-header__delete-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 9999px;
    background: transparent;
    color: oklch(var(--muted-foreground));
    border: none;
    box-shadow: none;
    transition: color 150ms ease, background-color 150ms ease;
  }
.ex-card-header__delete-btn:hover {
    color: oklch(var(--destructive));
    background-color: oklch(var(--muted));
  }
/* ─── Rest-tijd stepper — subtiele compacte dropdown in card header ───────
     Hergebruik de 28px pill-stijl van de timer-btn. Inset neumorphic shadow
     op de trigger, oranje accent op de geselecteerde waarde. Dutch label
     "Rest" + duur in seconden. Geen modals, volledig inline. */
.ex-rest-stepper {
    display: inline-flex;
    align-items: center;
  }
.ex-rest-stepper__trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    height: 28px;
    padding: 0 0.5rem;
    border-radius: 9999px;
    background-color: oklch(var(--muted));
    color: oklch(var(--muted-foreground));
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 600;
    border: none;
    box-shadow: var(--neomorph-inset-sm);
    transition: color 150ms ease, background-color 150ms ease, box-shadow 150ms
      ease;
    cursor: pointer;
  }
.ex-rest-stepper__trigger:hover {
    color: oklch(var(--accent));
    background-color: rgba(var(--accent-rgb), 0.1);
  }
.ex-rest-stepper__trigger:focus-visible {
    outline: none;
    box-shadow: var(--neomorph-inset-sm), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.6);
  }
.ex-rest-stepper__trigger[data-state="open"] {
    color: oklch(var(--accent));
    background-color: rgba(var(--accent-rgb), 0.12);
  }
.ex-rest-stepper__label {
    line-height: 1;
    white-space: nowrap;
  }
/* ─── Smalle schermen (≤380px) ─────────────────────────────────────────────
     Op hele smalle schermen verbergen we de "Rest " prefix zodat alleen de
     minuutwaarde (bv. "2 min") overblijft en de oefening-naam ruimte houdt.
     De prefix zit in een eigen <span class="ex-rest-stepper__prefix"> in
      ExerciseCard.tsx, dus alleen die prefix verdwijnt — de minuutwaarde
     blijft altijd zichtbaar. */
@media (max-width: 380px) {
    .ex-rest-stepper__prefix {
      display: none;
    }
  }
/* RPE toggle — subtiel icoon-knop, accent wanneer actief. Matcht de
     28px pill-stijl van de timer-btn en delete-btn. */
.ex-card-header__rpe-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 9999px;
    background-color: oklch(var(--muted));
    color: oklch(var(--muted-foreground));
    border: none;
    box-shadow: var(--neomorph-inset-sm);
    transition: color 150ms ease, background-color 150ms ease, box-shadow 150ms
      ease;
    cursor: pointer;
  }
.ex-card-header__rpe-btn:hover {
    color: oklch(var(--accent));
    background-color: rgba(var(--accent-rgb), 0.1);
  }
.ex-card-header__rpe-btn:focus-visible {
    outline: none;
    box-shadow: var(--neomorph-inset-sm), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.6);
  }
.ex-card-header__rpe-btn.is-active {
    background-color: var(--accent-hex);
    color: #ffffff;
    box-shadow: var(--neomorph-shadow-sm);
  }
/* ─── Per-exercise override indicator ──────────────────────────────────────
     Subtiele oranje stip rechtsboven op de RPE knop wanneer er een per-exercise
     override actief is. Zo is zichtbaar dat de oefening afwijkt van de globale
     standaard. Werkt in beide thema's via --accent-hex / --accent-rgb. */
.ex-card-header__rpe-btn.is-override {
    position: relative;
  }
.ex-card-header__rpe-btn.is-override::after {
    content: "";
    position: absolute;
    top: 2px;
    right: 2px;
    width: 6px;
    height: 6px;
    border-radius: 9999px;
    background-color: var(--accent-hex);
    box-shadow: 0 0 4px rgba(var(--accent-rgb), 0.7);
    pointer-events: none;
    z-index: 1;
  }
/* ─── Set table inside the card ─────────────────────────────────────────────
     Single header row (SET / KG / REPS, or SET / DURATION / DISTANCE, or
     SET / DURATION). No repeated labels per row. Tight, compact stack.
     NOTE: Each row (header + set rows) owns its own self-contained FLEXBOX
     column layout — mirroring the landing-page SetRowMini pattern. This avoids
     the display:contents grid-context bug where rows wrapped in non-grid
     parents lost their grid alignment and stacked vertically. */
.ex-card-table {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    width: 100%;
  }
/* Header row — tiny uppercase muted letter-spaced labels.
     Uses the same flex row pattern as set rows so column widths match. */
.ex-card-table-head-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0 0.25rem 0.0625rem;
  }
.ex-card-table-head {
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: oklch(var(--muted-foreground));
    line-height: 1;
    text-align: center;
    flex: 1 1 0;
    min-width: 0;
  }
.ex-card-table-head--index {
    flex: 0 0 28px;
    text-align: center;
  }
.ex-card-table-head--check {
    flex: 0 0 32px;
    text-align: center;
  }
/* Set row — self-contained flex row (one row per set). Index column +
     input columns + check column. Owns its own column widths so it never
     breaks alignment regardless of wrapper nesting (swipe wrapper, relative
     parent, etc.). Replaces the previous display:contents grid row which
     silently fell back to block flow when wrapped in non-grid parents.

     touch-action: pan-y lets the browser handle vertical scrolling natively
     (no double-tap-zoom delay, smooth scroll) while leaving horizontal
     panning to the JS swipe-to-delete handlers. Without this the browser
     would try to interpret both axes and the swipe would jitter. */
.ex-card-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    touch-action: pan-y;
  }
/* Value column — flex-1 so two value columns share the row equally.
      Holds the pill input (or countdown timer / unit select). Centered
      text alignment matches the header labels. */
.ex-card-row__col {
    flex: 1 1 0;
    min-width: 0;
    text-align: center;
  }
/* Set index — small centered number, fixed width matching the header. */
.ex-card-row__index {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 28px;
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 600;
    color: oklch(var(--muted-foreground));
    line-height: 1;
  }
/* Check column wrapper — fixed width matching the header check column,
      centers the checkmark button. */
.ex-card-row__check {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 32px;
  }
/* ─── Set row background distinction ────────────────────────────────────────
     Completed sets carry a light orange row background (subtle accent tint) so
     the user can scan completed vs pending sets at a glance. Pending sets use
     a neutral/muted background. The tint is applied to the .ex-card-row flex
     box itself (now a real box, not display:contents) with rounded corners and
     tight horizontal padding so the inputs/checkmark sit inside the tint. */
.ex-card-row {
    border-radius: 0.5rem;
    padding: 0.25rem 0.375rem;
    transition: background-color 200ms ease;
  }
.ex-card-row--pending {
    background-color: oklch(var(--muted) / 0.35);
  }
.ex-card-row--done {
    background-color: rgba(var(--accent-rgb), 0.14);
  }
/* Light-theme tuning: the muted tint is barely visible on a light bg, so
     bump the pending tint slightly and keep the completed orange tint. */
:root:not(.dark) .ex-card-row--pending {
    background-color: oklch(var(--muted) / 0.55);
  }
:root:not(.dark) .ex-card-row--done {
    background-color: rgba(var(--accent-rgb), 0.12);
  }
/* ─── Pill-shaped input fields ──────────────────────────────────────────────
     Fully rounded (border-radius pill), subtle low-contrast solid fill, NO hard
     borders (transparent), compact ~32-36px height, small centered font. Focus
     state shifts fill slightly + adds a faint accent ring — no border change. */
.ex-pill-input {
    width: 100%;
    height: 30px;
    border-radius: 9999px;
    border: 1px solid transparent;
    background-color: oklch(0.26 0 0);
    color: oklch(var(--foreground));
    font-family: var(--font-body);
    /* 1rem (16px) meets the iOS no-auto-zoom-on-focus threshold. The previous
       0.8125rem (13px) was overridden by @layer components over the base
       input[type=text]{font-size:16px} guard, triggering iOS auto-zoom. */
    font-size: 1rem;
    font-weight: 500;
    text-align: center;
    box-shadow: var(--neomorph-inset-sm);
    transition: background-color 150ms ease, box-shadow 150ms ease;
    /* Slightly tighter horizontal padding to keep the pill compact at the
       larger 16px font-size. */
    padding: 0 0.375rem;
  }
.ex-pill-input:focus {
    outline: none;
    background-color: oklch(0.3 0 0);
    /* Preserve the inset shadow and layer the accent ring on top of it. */
    box-shadow: var(--neomorph-inset-sm), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.55);
  }
.ex-pill-input:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
.ex-pill-input::-moz-placeholder {
    color: oklch(var(--muted-foreground) / 0.55);
    opacity: 1;
  }
.ex-pill-input::placeholder {
    color: oklch(var(--muted-foreground) / 0.55);
    opacity: 1;
  }
/* ─── Checkmarks ────────────────────────────────────────────────────────────
     Completed = solid orange (#E8630A) filled circle with white check icon.
     Pending = empty circle, 2px muted-gray border, transparent fill. */
.ex-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 9999px;
    flex-shrink: 0;
    border: 2px solid oklch(var(--muted-foreground) / 0.45);
    background-color: transparent;
    color: transparent;
    box-shadow: var(--neomorph-shadow-sm);
    transition: background-color 150ms ease, border-color 150ms ease, color
      150ms ease;
    cursor: pointer;
  }
.ex-check-pending {
    /* Toon altijd een vinkje — ook op pending sets. Subtiele grijze kleur
       zodat het Check icoon zichtbaar blijft zonder de oranje "voltooid"
       state na te bootsen. De base .ex-check heeft color: transparent; deze
       override maakt het icoon zichtbaar. Werkt in beide thema's via de
       geërfde --muted-foreground variabele. */
    color: oklch(var(--muted-foreground) / 0.55);
  }
.ex-check-done {
    border-color: var(--accent-hex);
    background-color: var(--accent-hex);
    color: #ffffff;
    /* Keep the raised neumorphic shadow on the completed orange state. */
    box-shadow: var(--neomorph-shadow-sm);
  }
.ex-check:hover:not(.ex-check-done) {
    border-color: oklch(var(--muted-foreground) / 0.75);
  }
/* ─── Inline rest timer strip ───────────────────────────────────────────────
      A thick (~36px) orange progress bar that appears UNDER the completed set
      row, with the countdown (mm:ss) centered INSIDE the bar. The bar fill
      advances behind the text. Auto-starts on set completion, disappears when
      timer elapses. NO controls — the timer simply counts down and vanishes. */
.ex-rest-strip {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.25rem 0.125rem;
    animation: ex-rest-strip-in 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.ex-rest-bar {
    flex: 1 1 auto;
    height: 36px;
    border-radius: 9999px;
    background-color: oklch(var(--muted) / 0.5);
    overflow: hidden;
    position: relative;
  }
.ex-rest-bar__fill {
    /* LEEGLOOP van rechts naar links: de fill start vol (pct=100%, hele bar
       oranje) en krimpt aan de linkerkant naarmate de tijd verstrijkt, tot
       pct=0% (bar leeg) bij afloop.

       ROBUSTE aanpak (drie verzekeringen gecombineerd):
       1. .ex-rest-bar heeft direction: rtl — absolute right-anchoring
          (right: 0; width: 100%) is deterministisch rechts-geankerd,
          onafhankelijk van de omringende LTR context.
       2. De fill heeft een VASTE width: 100% (altijd de hele bar breed)
          en wordt visueel gekrompen via een inline transform:
          scaleX(pct/100). transform-origin: 100% 50% (expliciete
          percentage-vorm, niet `right center` wat sommige browsers
          interpreteren als de rechterkant van de geschaalde box) anker
          de schaal aan de rechterkant van de originele box, dus bij
          afname van scaleX krimpt de fill aan de linkerkant en verschijnt
          er steeds meer lege ruimte rechts — een echte countdown-richting,
          thema-onafhankelijk en immuun voor box-model/positionering
          quirks die een width-aanpak kunnen breken.
       3. .ex-rest-bar__countdown heeft direction: ltr zodat de mm:ss
          tekst de rtl van de parent niet erft en gecentreerd blijft.

       De scaleX-waarde in ExerciseCard.tsx volgt de leegloop-formule:
       pct = 100 - Math.min(100, (liveElapsed / duration) * 100) — start bij
       1.0 (vol) en daalt naar 0.0 (leeg). right: 0 houdt de fill aan de
       rechterkant verankerd tijdens het schalen. */
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 100%;
    border-radius: 9999px;
    background-color: var(--accent-hex);
    /* transform-origin: 100% 50% is de expliciete percentage-vorm van
       `right center` en is deterministisch — sommige browsers
       interpreteren `right center` als de rechterkant van de
       getransformeerde (geschaalde) box in plaats van de originele box,
       waardoor de leegloop-richting kan omdraaien. 100% 50% verwijst
       altijd naar de originele box. */
    transform-origin: 100% 50%;
    /* scaleX wordt inline gezet door de component (leegloop-formule). */
  }
/* Countdown text — centered INSIDE the bar, over the fill. Uses mix-blend
     so the digits stay readable whether the orange fill has reached them or
     not (white text on the muted track, white on the orange fill). */
.ex-rest-bar__countdown {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-display);
    font-size: 0.875rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: #ffffff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
    pointer-events: none;
    z-index: 1;
    /* direction: ltr voorkomt dat de countdown-tekst de rtl-richting van
       de parent .ex-rest-bar erft — de mm:ss tekst moet gecentreerd en in
       normale LTR-volgorde blijven, ongeacht de rtl op de container die
       de fill-anchoring verzekert. */
    direction: ltr;
  }
/* ─── "Start rest" knop ────────────────────────────────────────────────────
      Compacte knop die verschijnt onder een voltooide set wanneer de globale
      auto-start setting uit staat. Visueel consistent met de rest-strip:
      accent-kleur, touch-manipulation voor directe tap-response, compacte
      padding. Alleen zichtbaar via JS-gating in SetRowComponent. */
.ex-rest-start-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 0.375rem 0.75rem;
    margin: 0.25rem 0 0.125rem;
    border: 1px solid oklch(var(--accent) / 0.45);
    border-radius: 9999px;
    background-color: oklch(var(--accent) / 0.12);
    color: var(--accent-hex);
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    line-height: 1;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: background-color 150ms ease, border-color 150ms ease, transform
      120ms ease;
  }
.ex-rest-start-btn:hover {
    background-color: oklch(var(--accent) / 0.2);
    border-color: oklch(var(--accent) / 0.65);
  }
.ex-rest-start-btn:active {
    transform: scale(0.97);
  }
.ex-rest-start-btn:focus-visible {
    outline: 2px solid var(--accent-hex);
    outline-offset: 2px;
  }
@keyframes ex-rest-strip-in {
    from {
      opacity: 0;
      transform: translateY(-2px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
/* ─── Ghost "+ Add Set" button ──────────────────────────────────────────────
      No dashed border. Subtle pill container with a light gray fill so the
      action is visible but not dominant. Full-width, centered, compact. */
.ex-add-set-wrap {
    display: flex;
    justify-content: center;
    width: 100%;
    padding: 0 0.25rem;
  }
.ex-add-set-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    width: 100%;
    height: 30px;
    padding: 0 0.75rem;
    margin-top: 0.375rem;
    background-color: oklch(0.26 0 0);
    border: none;
    border-radius: 9999px;
    color: oklch(var(--muted-foreground));
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 600;
    box-shadow: none;
    transition: color 150ms ease, background-color 150ms ease;
    cursor: pointer;
  }
.ex-add-set-btn:hover:not(:disabled) {
    color: oklch(var(--foreground));
    background-color: oklch(var(--muted) / 0.6);
  }
.ex-add-set-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
/* ─── Card shell shared by all three card types ─────────────────────────────
     The actual card surface that hosts the table + add-set button. Subtle
     raised neumorphic-sm surface, rounded-xl, tight padding. */
.ex-card-shell {
  border-radius: 0.75rem;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .ex-card-shell {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .ex-card-shell {
    border: 1px solid oklch(var(--border));
  }
}
.ex-card-shell {
    padding: 0.625rem 0.625rem 0.5rem;
  }
/* ─── Light-theme overrides for ex-pill-input ────────────────────────────────
      The base .ex-pill-input uses oklch(0.22 0 0) (dark fill) which is unreadable
      in light mode with dark text. These :root:not(.dark) overrides swap the fill
      to a subtle light gray (oklch(0.96 0 0)) and keep the focus accent ring.
      The inset neumorphic shadow is inherited from the base rule (var(--neomorph-inset-sm)
      resolves to the light-theme token here) and is preserved on focus alongside
      the accent ring. */
:root:not(.dark) .ex-pill-input {
    background-color: oklch(0.94 0 0) !important;
    color: oklch(0.15 0 0) !important;
    box-shadow: var(--neomorph-inset-sm) !important;
  }
:root:not(.dark) .ex-pill-input:focus {
    background-color: oklch(0.92 0 0) !important;
    box-shadow: var(--neomorph-inset-sm), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.55) !important;
  }
:root:not(.dark) .ex-pill-input::-moz-placeholder {
    color: oklch(0.45 0 0 / 0.6) !important;
    opacity: 1 !important;
  }
:root:not(.dark) .ex-pill-input::placeholder {
    color: oklch(0.45 0 0 / 0.6) !important;
    opacity: 1 !important;
  }
/* Light-theme check pending border — darker gray for visibility on light bg */
:root:not(.dark) .ex-check {
    border-color: oklch(0.55 0 0 / 0.5);
  }
/* Light-theme add-set button — subtle light gray fill matching the pill
     inputs so the ghost container reads as a quiet action surface. */
:root:not(.dark) .ex-add-set-btn {
    background-color: oklch(0.94 0 0) !important;
  }
:root:not(.dark) .ex-add-set-btn:hover:not(:disabled) {
    background-color: oklch(var(--muted) / 0.6) !important;
  }
/* ─────────────────────────────────────────────────────────────────────────── */
/* Neumorphic Hover States — scale only, no translateY to avoid layout shifts */
.neomorph-hover {
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 200ms
      cubic-bezier(0.4, 0, 0.2, 1);
  }
.neomorph-hover:hover {
    box-shadow: var(--neomorph-hover);
    transform: scale(1.01) translateZ(0);
  }
.neomorph-hover:active {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.99) translateZ(0);
  }
/* Neumorphic Button States — scale only, contain layout to prevent shift */
.neomorph-button {
    box-shadow: var(--neomorph-shadow);
    transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
      cubic-bezier(0.4, 0, 0.2, 1), opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
    contain: layout style;
  }
.neomorph-button:hover:not(:disabled) {
    box-shadow: var(--neomorph-hover);
    transform: scale(1.02) translateZ(0);
  }
.neomorph-button:active:not(:disabled) {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.98) translateZ(0);
  }
.neomorph-button:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
  }
.neomorph-button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
/* Neumorphic Accent Glow — scale only */
.neomorph-accent {
    box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.16), -4px -4px 10px
      rgba(255, 255, 255, 0.9), 0 0 22px oklch(var(--accent) / 0.5);
    transition: box-shadow 400ms cubic-bezier(0.4, 0, 0.2, 1), transform 400ms
      cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
  }
.neomorph-accent:hover {
    box-shadow: 5px 5px 12px rgba(0, 0, 0, 0.18), -5px -5px 12px
      rgba(255, 255, 255, 0.95), 0 0 26px oklch(var(--accent) / 0.6);
    transform: scale(1.02) translateZ(0);
  }
.dark .neomorph-accent {
    box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.45), -4px -4px 8px
      rgba(255, 255, 255, 0.04), 0 0 16px oklch(var(--accent) / 0.4);
  }
.dark .neomorph-accent:hover {
    box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.52), -5px -5px 10px
      rgba(255, 255, 255, 0.05), 0 0 18px oklch(var(--accent) / 0.48);
    transform: scale(1.02) translateZ(0);
  }
/* Neumorphic Pressed State */
/* Template Card — slower transition is fine for card hover */
/* Legacy glass utilities for compatibility */
/* Enhanced Touch Interactions */
.touch-manipulation {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    min-height: 44px;
    min-width: 44px;
  }
/* Scroll-list container — disables pull-to-refresh and scroll chaining so
     vertical scroll inside the list (History, Templates, Exercises) doesn't
     trigger the browser's native pull-to-refresh gesture or bubble up to a
     parent scroller. This prevents conflicts with swipe-to-delete on
     ExerciseCard set rows: the page can scroll vertically without the
     browser hijacking the gesture for a refresh, and the JS swipe handlers
     own horizontal panning via touch-action: pan-y on .ex-card-row. */
.scroll-list {
    overscroll-behavior-y: contain;
  }
/* Icon Button Consistent Sizing */
/* Template Card Action Button — contain layout to prevent press from shifting siblings */
.template-action-button {
  flex-shrink: 0;
  touch-action: manipulation;
  border-radius: var(--radius);
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow);
    transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
      cubic-bezier(0.4, 0, 0.2, 1), opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
    contain: layout style;
}
.template-action-button:hover:not(:disabled) {
    box-shadow: var(--neomorph-hover);
    transform: scale(1.02) translateZ(0);
  }
.template-action-button:active:not(:disabled) {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.98) translateZ(0);
  }
.template-action-button:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
  }
.template-action-button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
.template-action-button {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    min-height: 44px;
    min-width: 44px;
  }
@media (prefers-reduced-motion: reduce) {

  .template-action-button {
    transition: none;
    transform: none;
  }
}
.template-action-button {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
      cubic-bezier(0.4, 0, 0.2, 1);
    contain: layout style;
  }
.template-action-button:active {
    transform: scale(0.95) translateZ(0);
  }
/* Uniform Input Field Sizing */
/* Consistent Card Sizing */
/* ═══════════════════════════════════════════════════════════════════════════
     PWA INSTALL-FUNNEL LANDING PAGE
     Marketing/install surface shown only to browser visitors. Purely additive
     utilities — reuses existing neumorphic + accent tokens (--accent,
     --accent-hex, --accent-rgb, --neomorph-shadow, --neomorph-hover,
     --neomorph-pressed). No existing tokens modified; works in both :root
     (light) and .dark themes via inherited variables. Style rules: veel
     witruimte, max 2 accent-momenten per scherm, subtiele fade-in bij scrollen,
     snelle laadtijd, mobiel-eerst.
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Hero spacing helpers ─────────────────────────────────────────────────
      Generous vertical rhythm for the landing hero and section gaps. Mobile-
      first base values scale up at sm/md/lg via the responsive utilities. */
.landing-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
    min-height: 70vh;
    padding-top: clamp(3rem, 10vh, 6rem);
    padding-bottom: clamp(3rem, 10vh, 6rem);
}
.landing-section {
  width: 100%;
    padding-top: clamp(2.5rem, 7vw, 4rem);
    padding-bottom: clamp(2.5rem, 7vw, 4rem);
}
/* ─── Fade-in-on-scroll utility ────────────────────────────────────────────
      Subtle entrance: opacity 0 → 1 + translateY(12px → 0) over 500ms with a
      soft cubic-bezier. Triggered by an IntersectionObserver adding
      .is-visible (frontend responsibility). Honors prefers-reduced-motion via
      the global rule. No heavy animations, no bounce. */
.fade-in-up {
    opacity: 0;
    transform: translateY(12px);
    transition: opacity 500ms cubic-bezier(0.4, 0, 0.2, 1), transform 500ms
      cubic-bezier(0.4, 0, 0.2, 1);
    will-change: opacity, transform;
  }
.fade-in-up.is-visible {
    opacity: 1;
    transform: translateY(0);
  }
/* Staggered children: apply .fade-in-up-stagger to a parent and
     .fade-in-up to children; each child delays by its index × 80ms (capped at
     6 via the nth-child rules below). Keeps the cascade subtle and fast. */
.fade-in-up-stagger > .fade-in-up:nth-child(1) {
    transition-delay: 0ms;
  }
.fade-in-up-stagger > .fade-in-up:nth-child(2) {
    transition-delay: 80ms;
  }
.fade-in-up-stagger > .fade-in-up:nth-child(3) {
    transition-delay: 160ms;
  }
.fade-in-up-stagger > .fade-in-up:nth-child(4) {
    transition-delay: 240ms;
  }
.fade-in-up-stagger > .fade-in-up:nth-child(5) {
    transition-delay: 320ms;
  }
.fade-in-up-stagger > .fade-in-up:nth-child(6) {
    transition-delay: 400ms;
  }
/* ─── Feature card hover state ─────────────────────────────────────────────
      A landing-specific variant of .neomorph for the 3 feature cards. Reuses
      the existing --neomorph-shadow / --neomorph-hover tokens but adds a
      faint accent ring on hover to signal interactivity without breaking the
      "max 2 accent moments" rule (hover is transient, not a static accent).
      Scale only — no translateY, no layout shift. */
.landing-feature-card {
  border-radius: 1rem;
  background-color: oklch(var(--background));
  padding: 1.25rem;
    box-shadow: var(--neomorph-shadow), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .landing-feature-card {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .landing-feature-card {
    border: 1px solid oklch(var(--border));
  }
}
@media (min-width: 640px) {

  .landing-feature-card {
    padding: 1.5rem;
  }
}
.landing-feature-card {
    transition: box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1), transform 250ms
      cubic-bezier(0.4, 0, 0.2, 1), border-color 250ms
      cubic-bezier(0.4, 0, 0.2, 1);
    border: 1px solid transparent;
    will-change: transform;
  }
.landing-feature-card:hover {
    box-shadow: var(--neomorph-hover), 0 0 0 1px rgba(var(--accent-rgb), 0.18);
    transform: scale(1.015) translateZ(0);
  }
.landing-feature-card:active {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.99) translateZ(0);
  }
/* Signature feature card — the ONE feature card allowed to carry a static
     accent moment (subtle corner glow). Reuses the existing .accent-glow
     radial pattern but tuned softer for the landing context. */
.dark .landing-feature-card--signature::before {
    background: radial-gradient(
      circle,
      rgba(var(--accent-rgb), 0.18) 0%,
      transparent 70%
    );
  }
/* ─── Feature icon well ────────────────────────────────────────────────────
      Small recessed neumorphic circle hosting the feature icon. Reuses
      --neomorph-inset-sm. 44px touch-target-friendly, centered icon. */
/* ─── Hero CTA cluster ────────────────────────────────────────────────────
      Primary = neomorph-accent (orange glow, the hero's single accent moment).
      Secondary = flat muted text link, no card, no shadow — keeps the second
      accent slot free for the signature feature card. */
.landing-cta-primary {
  touch-action: manipulation;
  border-radius: 1rem;
    box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.16), -4px -4px 10px
      rgba(255, 255, 255, 0.9), 0 0 22px oklch(var(--accent) / 0.5);
    transition: box-shadow 400ms cubic-bezier(0.4, 0, 0.2, 1), transform 400ms
      cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
}
.landing-cta-primary:hover {
    box-shadow: 5px 5px 12px rgba(0, 0, 0, 0.18), -5px -5px 12px
      rgba(255, 255, 255, 0.95), 0 0 26px oklch(var(--accent) / 0.6);
    transform: scale(1.02) translateZ(0);
  }
.dark .landing-cta-primary {
    box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.45), -4px -4px 8px
      rgba(255, 255, 255, 0.04), 0 0 16px oklch(var(--accent) / 0.4);
  }
.dark .landing-cta-primary:hover {
    box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.52), -5px -5px 10px
      rgba(255, 255, 255, 0.05), 0 0 18px oklch(var(--accent) / 0.48);
    transform: scale(1.02) translateZ(0);
  }
.landing-cta-primary {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    min-width: 44px;
    background-color: var(--accent-hex);
    color: #ffffff;
    font-family: var(--font-display);
    font-weight: 700;
    padding: 0.875rem 2rem;
    min-height: 52px;
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.4), 0 8px 24px
      rgba(var(--accent-rgb), 0.35), 0 0 22px oklch(var(--accent) / 0.5);
  }
.dark .landing-cta-primary {
    background-color: var(--accent-hex);
    color: #ffffff;
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.5), 0 8px 24px
      rgba(var(--accent-rgb), 0.4), 0 0 18px oklch(var(--accent) / 0.45);
  }
.landing-cta-secondary {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    min-width: 44px;
    background: transparent;
    color: oklch(var(--muted-foreground));
    font-family: var(--font-body);
    font-weight: 500;
    padding: 0.75rem 1.25rem;
    min-height: 44px;
    transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.landing-cta-secondary:hover {
    color: oklch(var(--foreground));
  }
/* ─── Accent CTA pill (accountability block) ──────────────────────────────
      A compact accent pill for mid-page conversion nudges. Smaller than the
      hero CTA so it doesn't compete — uses accent-dim fill + accent text,
      no glow, keeping the "max 2 accent moments" budget intact. */
/* ─── FAQ collapsible row ─────────────────────────────────────────────────
      Minimal neumorphic-sm row for the FAQ section. Privacy lives here as a
      single FAQ question (per user preference) — not in the emotional core.
      Uses .neomorph-sm for a quiet raised surface; chevron rotates on open. */
.landing-faq-row {
  border-radius: 0.75rem;
  background-color: oklch(var(--background));
  padding-left: 1rem;
  padding-right: 1rem;
  padding-top: 0.75rem;
  padding-bottom: 0.75rem;
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .landing-faq-row {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .landing-faq-row {
    border: 1px solid oklch(var(--border));
  }
}
.landing-faq-row {
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.landing-faq-row[aria-expanded="true"] {
    box-shadow: var(--neomorph-inset-sm);
  }
/* ─── Footer ──────────────────────────────────────────────────────────────
      Quiet, low-contrast footer. Privacy link + minimal nav. No card, no
      shadow — sits flat on bg-background with a top border for separation. */
.landing-footer {
  width: 100%;
  border-top-width: 1px;
    border-color: oklch(var(--border) / 0.5);
    padding-top: clamp(2rem, 5vw, 3rem);
    padding-bottom: clamp(2rem, 5vw, 3rem);
}
/* ═══════════════════════════════════════════════════════════════════════════
     PREMIUM LANDING — gravl.ai-level marketing page utilities.
     Purely additive — reuses existing --accent / --accent-hex / --accent-rgb /
     --accent-dim / --neomorph-* tokens and inherited :root + .dark variables.
     No existing tokens modified. Mobile-first; clamp-based scaling for desktop.
     Rules: veel witruimte, max 2 accent-momenten per scherm, subtiele fade-in,
     mobiel-eerst, werkt in licht én donker.
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Premium hero typography scale ────────────────────────────────────────
     Very bold display with breathing room. Space Grotesk, tight tracking,
     clamp-based so it scales from mobile (~2.5rem) to desktop (~5.5rem) without
     overflowing. Line-height 1.05 keeps the three-word headline tight. The
     .landing-hero-headline--accent span carries the single accent word ("Groei.")
     — counts as accent moment #1 alongside the hero CTA. */
.landing-hero-headline {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1.05;
    font-size: clamp(2.5rem, 7vw, 5.5rem);
    color: oklch(var(--foreground));
  }
.landing-hero-subline {
    font-family: var(--font-body);
    font-weight: 400;
    line-height: 1.55;
    font-size: clamp(1rem, 2.2vw, 1.25rem);
    color: oklch(var(--muted-foreground));
    max-width: 42ch;
  }
/* ─── Section headline scale (feature/accountability/install) ──────────────
     Slightly smaller than hero but still bold and confident. Tight tracking,
     clamp 1.75rem→2.75rem. Used for feature section titles, accountability
     block headline, and install section headline. */
.landing-section-headline {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.15;
    font-size: clamp(1.75rem, 4vw, 2.75rem);
    color: oklch(var(--foreground));
  }
.landing-section-body {
    font-family: var(--font-body);
    font-weight: 400;
    line-height: 1.6;
    font-size: clamp(0.95rem, 1.8vw, 1.0625rem);
    color: oklch(var(--muted-foreground));
    max-width: 52ch;
  }
/* ─── CSS phone-frame device mockup ───────────────────────────────────────
     A pure-CSS phone frame with rounded corners, notch, and an inner scrollable
     viewport that hosts read-only rendered app components (ExerciseCard,
     OverloadCurveChart). The frame is a fixed-aspect bezel; the inner viewport
     scrolls vertically with momentum scrolling (like gravl.ai). The
     .landing-phone-glow sibling/parent provides the accent radial behind it.

     .landing-phone            — outer bezel (dark, rounded-[2.5rem], border)
     .landing-phone__notch     — top centered pill notch
     .landing-phone__screen    — inner viewport, overflow-y auto, momentum scroll
     .landing-phone-glow        — absolute radial accent glow positioned behind

     Sizes are clamp-based: ~280px wide on mobile, ~340px on desktop. Aspect
     ratio ~9/19.5 kept via aspect-ratio so it never collapses. */
.landing-phone {
    position: relative;
    width: clamp(260px, 32vw, 340px);
    aspect-ratio: 9 / 19.5;
    border-radius: 2.5rem;
    background-color: oklch(var(--card));
    border: 1px solid oklch(var(--border) / 0.7);
    box-shadow: var(--neomorph-shadow-xl);
    padding: 0.5rem;
    overflow: hidden;
    flex-shrink: 0;
  }
.dark .landing-phone {
    background-color: #161616;
    border-color: oklch(var(--border) / 0.5);
  }
.landing-phone__notch {
    position: absolute;
    top: 0.5rem;
    left: 50%;
    transform: translateX(-50%);
    width: 32%;
    height: 1.25rem;
    border-radius: 0 0 1rem 1rem;
    background-color: #0a0a0a;
    z-index: 2;
    pointer-events: none;
  }
.landing-phone__screen {
    position: relative;
    width: 100%;
    height: 100%;
    border-radius: 2rem;
    background-color: oklch(var(--background));
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 2rem 0.75rem 0.75rem;
  }
.landing-phone__screen::-webkit-scrollbar {
    display: none;
  }
/* ─── Accent glow behind the phone ─────────────────────────────────────────
     A large, soft radial accent glow positioned behind the phone frame. Uses
     --accent-rgb so it tints correctly in both themes. This is a decorative
     ambient element — does NOT count as an accent "moment" (it's diffuse, not a
     solid fill). Pointer-events none so it never blocks interaction. */
.landing-phone-glow {
    position: absolute;
    inset: -10% -10% auto auto;
    width: 70%;
    height: 70%;
    border-radius: 50%;
    background: radial-gradient(
      circle,
      rgba(var(--accent-rgb), 0.16) 0%,
      transparent 65%
    );
    pointer-events: none;
    z-index: 0;
    filter: blur(8px);
    transform: translateZ(0);
  }
.dark .landing-phone-glow {
    background: radial-gradient(
      circle,
      rgba(var(--accent-rgb), 0.22) 0%,
      transparent 65%
    );
  }
/* ─── Alternating feature-section layout helpers ──────────────────────────
     Mobile-first: every feature section stacks text-above-mini-render (per user
     preference — text first on mobile). On md+ desktop, sections alternate
     left/right via .landing-feature-row--reverse (row-reverse). The mini-render
     lives in a neomorph-sm well so it reads as a real product snippet, not a
     screenshot.

     .landing-feature-row            — grid, 1 col mobile, 2 col md+
     .landing-feature-row--reverse   — md+ row-reverse for alternation
     .landing-feature-row__text      — text column (headline + body + icon)
     .landing-feature-row__render    — mini-render column
     .landing-mini-render            — neomorph-sm well hosting the mini-render
  */
.landing-feature-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.5rem, 3vw, 2.5rem);
    align-items: center;
  }
@media (min-width: 768px) {
    .landing-feature-row {
      grid-template-columns: 1fr 1fr;
      gap: clamp(2.5rem, 5vw, 4rem);
    }
    .landing-feature-row--reverse {
      direction: rtl;
    }
    .landing-feature-row--reverse > * {
      direction: ltr;
    }
  }
.landing-feature-row__text {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
  }
.landing-feature-row__render {
    display: flex;
    justify-content: center;
    align-items: center;
  }
.landing-mini-render {
  border-radius: 1rem;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .landing-mini-render {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .landing-mini-render {
    border: 1px solid oklch(var(--border));
  }
}
.landing-mini-render {
    width: 100%;
    max-width: 360px;
    padding: 1rem;
  }
/* ─── Accountability block (emotional core) ──────────────────────────────
     A large, wide neomorph card carrying the emotional headline. Generous
     padding (clamp 2.5rem→4rem), centered text, the headline in display font,
     and three short muted lines beneath. This is the page's emotional anchor —
     no accent fill here (keeps the 2-accent budget for hero CTA + signature
     feature card). The .landing-cta-pill can appear centered below if desired. */
/* ─── Privacy manifest block (replaces accountability) ───────────────────
     Same neomorph card treatment as the former accountability block so the
     page rhythm is preserved. Shield icon in an inset circle, display
     headline, three short lines, and one closing muted line. No accent fill —
     keeps the 2-accent budget for hero CTA + signature feature card. */
.landing-privacy {
  border-radius: 1.5rem;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .landing-privacy {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .landing-privacy {
    border: 1px solid oklch(var(--border));
  }
}
.landing-privacy {
    padding: clamp(2.5rem, 6vw, 4rem) clamp(1.5rem, 5vw, 3.5rem);
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
  }
.landing-privacy__headline {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.2;
    font-size: clamp(1.5rem, 4vw, 2.5rem);
    color: oklch(var(--foreground));
    max-width: 24ch;
  }
.landing-privacy__lines {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    font-family: var(--font-body);
    font-size: clamp(0.875rem, 1.8vw, 1rem);
    color: oklch(var(--muted-foreground));
  }
.landing-privacy__closing {
    font-family: var(--font-body);
    font-size: clamp(0.8125rem, 1.6vw, 0.9375rem);
    color: oklch(var(--muted-foreground) / 0.85);
    max-width: 38ch;
    line-height: 1.5;
  }
/* ─── Premium install section card ────────────────────────────────────────
     A centered, elevated neomorph card hosting the platform-detected install
     flow. Larger radius (rounded-3xl) and extra padding to feel premium. The
     install headline uses .landing-section-headline. The accent CTA pill
     (.landing-cta-pill) appears here — does not count against the 2-accent
     budget because it's a tint, not a glow. */
.landing-install-card {
  border-radius: 1.5rem;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow-lg), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .landing-install-card {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .landing-install-card {
    border: 1px solid oklch(var(--border));
  }
}
.landing-install-card {
    padding: clamp(2rem, 5vw, 3.5rem) clamp(1.5rem, 5vw, 3rem);
    max-width: 640px;
    margin-inline: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.5rem;
    text-align: center;
  }
.landing-install-steps {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: 100%;
    max-width: 360px;
  }
.landing-install-step {
  border-radius: 0.75rem;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .landing-install-step {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .landing-install-step {
    border: 1px solid oklch(var(--border));
  }
}
.landing-install-step {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    text-align: left;
  }
.landing-install-step__number {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-inset-sm);
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.8125rem;
    color: oklch(var(--accent));
}
/* ─── Inline Privacy / Voorwaarden collapsibles (footer) ──────────────────
     Compact collapsible summaries living inline in the footer. A summary line
     + "Lees meer" expander that reveals 3-5 lines of inline text. Uses a
     <details>-friendly styling pattern but works with any toggle. The
     [aria-expanded] attribute drives the chevron rotation. No accent fill —
     keeps the footer quiet. */
.landing-inline-legal {
    border-top: 1px solid oklch(var(--border) / 0.4);
    padding-top: 1rem;
    margin-top: 1rem;
  }
.landing-inline-legal__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    cursor: pointer;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 0.875rem;
    color: oklch(var(--foreground));
    padding: 0.25rem 0;
    list-style: none;
  }
.landing-inline-legal__summary::-webkit-details-marker {
    display: none;
  }
.landing-inline-legal__chevron {
    flex-shrink: 0;
    color: oklch(var(--muted-foreground));
    transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.landing-inline-legal[open] .landing-inline-legal__chevron,
  .landing-inline-legal__summary[aria-expanded="true"]
    .landing-inline-legal__chevron {
    transform: rotate(180deg);
  }
.landing-inline-legal__body {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.8125rem;
    line-height: 1.6;
    color: oklch(var(--muted-foreground));
    padding: 0.5rem 0 0.75rem;
    max-width: 60ch;
  }
/* ─── Footer brand + tagline ──────────────────────────────────────────────
     The footer brand line: Repstat name in display font + tagline "Log. Train
     samen. Groei." in muted body. Sits above the inline legal collapsibles. */
.landing-footer__brand {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.01em;
    font-size: 1.125rem;
    color: oklch(var(--foreground));
  }
.landing-footer__tagline {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.8125rem;
    color: oklch(var(--muted-foreground));
    margin-top: 0.25rem;
  }
/* ─── Extended fade-in-up variants for premium landing ───────────────────
     The base .fade-in-up (opacity 0→1, translateY 12px→0, 500ms) already exists.
     These variants add a slightly larger translate for hero/headline elements
     (more dramatic entrance) and a smaller translate for inline rows (subtler).
     All honor prefers-reduced-motion via the existing global guard. */
.fade-in-up--lg {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity 600ms cubic-bezier(0.4, 0, 0.2, 1), transform 600ms
      cubic-bezier(0.4, 0, 0.2, 1);
    will-change: opacity, transform;
  }
.fade-in-up--lg.is-visible {
    opacity: 1;
    transform: translateY(0);
  }
.fade-in-up--sm {
    opacity: 0;
    transform: translateY(8px);
    transition: opacity 400ms cubic-bezier(0.4, 0, 0.2, 1), transform 400ms
      cubic-bezier(0.4, 0, 0.2, 1);
    will-change: opacity, transform;
  }
.fade-in-up--sm.is-visible {
    opacity: 1;
    transform: translateY(0);
  }
/* ─── Reduced motion guard ────────────────────────────────────────────────
      Landing fade-in-up is decorative — disable it entirely for users who
      prefer reduced motion. Content appears instantly. */
@media (prefers-reduced-motion: reduce) {
    .fade-in-up,
    .fade-in-up--lg,
    .fade-in-up--sm {
      opacity: 1;
      transform: none;
      transition: none;
    }
    .landing-feature-card,
    .landing-cta-primary,
    .landing-cta-pill,
    .landing-cta-secondary,
    .landing-inline-legal__chevron {
      transition: none;
    }
  }
/* ═══════════════════════════════════════════════════════════════════════════
     EXTENDED LANDING — sticky nav, feature grid, social proof, pricing.
     Purely additive — reuses existing --accent-hex / --accent-rgb /
     --accent-dim / --neomorph-* / --font-display / --font-body tokens.
     No existing tokens modified. Mobile-first; clamp-based scaling.
     Rules: neumorphic dark + oranje accent, max 2 accent-momenten per scherm,
     subtiele fade-in, premium gamified look consistent met de app.
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Sticky header / nav ──────────────────────────────────────────────────
      Sticky top header met REPSTAT logo links, anker-links naar secties in
      het midden (verborgen op mobile), en een oranje accent CTA rechts.
      Neumorphic dark bg met backdrop-blur voor premium feel. Blijft zichtbaar
      bij scrollen. Mobile: alleen logo + CTA; md+: logo + links + CTA. */
.landing-nav {
    position: sticky;
    top: 0;
    z-index: 50;
    width: 100%;
    background-color: oklch(var(--background) / 0.82);
    backdrop-filter: blur(14px) saturate(140%);
    -webkit-backdrop-filter: blur(14px) saturate(140%);
    border-bottom: 1px solid oklch(var(--border) / 0.4);
    padding: 0.75rem clamp(1rem, 4vw, 2rem);
    transition: box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1), background-color
      250ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.landing-nav.is-scrolled {
    box-shadow: var(--neomorph-shadow-sm);
    background-color: oklch(var(--background) / 0.92);
  }
.dark .landing-nav {
    background-color: oklch(var(--background) / 0.78);
    border-bottom-color: oklch(var(--border) / 0.5);
  }
.dark .landing-nav.is-scrolled {
    background-color: oklch(var(--background) / 0.9);
  }
.landing-nav__inner {
    max-width: 1120px;
    margin-inline: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
  }
.landing-nav__logo {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.02em;
    font-size: 1.125rem;
    color: oklch(var(--accent));
    text-decoration: none;
    flex-shrink: 0;
  }
.landing-nav__links {
    display: none;
    align-items: center;
    gap: 1.75rem;
    margin-inline: auto;
  }
.landing-nav__links button {
    font-family: var(--font-body);
    font-weight: 500;
    font-size: 0.875rem;
    color: oklch(var(--muted-foreground));
    text-decoration: none;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1);
  }
.landing-nav__links button:hover {
    color: oklch(var(--foreground));
  }
.landing-nav__cta {
  touch-action: manipulation;
  border-radius: 9999px;
    box-shadow: var(--neomorph-shadow);
    transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
      cubic-bezier(0.4, 0, 0.2, 1), opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
    contain: layout style;
}
.landing-nav__cta:hover:not(:disabled) {
    box-shadow: var(--neomorph-hover);
    transform: scale(1.02) translateZ(0);
  }
.landing-nav__cta:active:not(:disabled) {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.98) translateZ(0);
  }
.landing-nav__cta:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
  }
.landing-nav__cta:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
.landing-nav__cta {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    min-height: 44px;
    min-width: 44px;
  }
.landing-nav__cta:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
    border-radius: inherit;
  }
@media (prefers-reduced-motion: reduce) {

  .landing-nav__cta {
    transition: none;
    transform: none;
  }
}
.landing-nav__cta {
    background-color: var(--accent-hex);
    color: #ffffff;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.875rem;
    padding: 0.5rem 1.25rem;
    min-height: 40px;
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.35), 0 4px 14px
      rgba(var(--accent-rgb), 0.28), 0 0 14px oklch(var(--accent) / 0.35);
    transition: box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1), transform 250ms
      cubic-bezier(0.4, 0, 0.2, 1);
    flex-shrink: 0;
  }
.landing-nav__cta:hover {
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.5), 0 6px 18px
      rgba(var(--accent-rgb), 0.38), 0 0 18px oklch(var(--accent) / 0.5);
    transform: translateY(-1px) translateZ(0);
  }
.landing-nav__cta:active {
    box-shadow: var(--neomorph-pressed);
    transform: translateY(0) translateZ(0);
  }
@media (min-width: 768px) {
    .landing-nav__links {
      display: flex;
    }
  }
/* ─── Extended feature grid (6 compact cards) ──────────────────────────────
      Responsive CSS grid: 1 col mobile, 2 col tablet (md), 3 col desktop (lg).
      Elke card is een raised neumorphic surface met een oranje accent icon
      well, titel in Space Grotesk en beschrijving in General Sans (muted).
      Hover: subtiele accent ring (transient, telt niet mee als accent moment). */
.landing-feature-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1rem, 2.5vw, 1.5rem);
    max-width: 1120px;
    margin-inline: auto;
    width: 100%;
  }
@media (min-width: 640px) {
    .landing-feature-grid {
      grid-template-columns: repeat(2, 1fr);
    }
  }
@media (min-width: 1024px) {
    .landing-feature-grid {
      grid-template-columns: repeat(3, 1fr);
    }
  }
.landing-feature-card {
  border-radius: 1rem;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .landing-feature-card {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .landing-feature-card {
    border: 1px solid oklch(var(--border));
  }
}
.landing-feature-card {
    padding: clamp(1.25rem, 2.5vw, 1.75rem);
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    border: 1px solid transparent;
    transition: box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1), transform 250ms
      cubic-bezier(0.4, 0, 0.2, 1), border-color 250ms
      cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
  }
.landing-feature-card:hover {
    box-shadow: var(--neomorph-hover), 0 0 0 1px rgba(var(--accent-rgb), 0.18);
    transform: translateY(-2px) translateZ(0);
  }
.landing-feature-card:active {
    box-shadow: var(--neomorph-pressed);
    transform: translateY(0) translateZ(0);
  }
.landing-feature-card__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0.75rem;
    box-shadow: var(--neomorph-inset-sm);
    width: 48px;
    height: 48px;
    color: oklch(var(--accent));
    flex-shrink: 0;
    background-color: oklch(var(--background));
}
.landing-feature-card__title {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.01em;
    font-size: clamp(1rem, 2vw, 1.125rem);
    line-height: 1.25;
    color: oklch(var(--foreground));
  }
.landing-feature-card__desc {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.875rem;
    line-height: 1.55;
    color: oklch(var(--muted-foreground));
  }
/* ─── Pricing sectie ───────────────────────────────────────────────────────
      Eén pricing card die duidelijk maakt dat Repstat gratis is, gehost op
      Internet Computer. Neumorphic card met oranje accent rand/glow (dit is
      het tweede accent moment naast de hero CTA). Bevat badge "Gratis",
      grote prijs, korte uitleg, feature-lijst met checkmarks en CTA. */
.landing-pricing {
  width: 100%;
    padding-top: clamp(2.5rem, 7vw, 4rem);
    padding-bottom: clamp(2.5rem, 7vw, 4rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.landing-pricing-card {
  border-radius: 1.5rem;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow-lg), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .landing-pricing-card {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .landing-pricing-card {
    border: 1px solid oklch(var(--border));
  }
}
.landing-pricing-card {
    position: relative;
    max-width: 480px;
    width: 100%;
    padding: clamp(2rem, 5vw, 3rem) clamp(1.5rem, 4vw, 2.5rem);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    text-align: center;
    border: 1px solid rgba(var(--accent-rgb), 0.35);
    box-shadow: var(--neomorph-shadow-xl), 0 0 0 1px
      rgba(var(--accent-rgb), 0.2), 0 0 32px rgba(var(--accent-rgb), 0.18);
  }
.dark .landing-pricing-card {
    border-color: rgba(var(--accent-rgb), 0.45);
    box-shadow: var(--neomorph-shadow-xl), 0 0 0 1px
      rgba(var(--accent-rgb), 0.3), 0 0 36px rgba(var(--accent-rgb), 0.22);
  }
.landing-pricing-card__badge {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    min-height: 44px;
    min-width: 44px;
    display: inline-flex;
    align-items: center;
    padding: 0.375rem 1rem;
    border-radius: 9999px;
    background-color: var(--accent-hex);
    color: #ffffff;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.75rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.4), 0 4px 12px
      rgba(var(--accent-rgb), 0.3), 0 0 14px oklch(var(--accent) / 0.35);
}
.landing-pricing-card__price {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.03em;
    line-height: 1;
    font-size: clamp(3rem, 8vw, 4.5rem);
    color: oklch(var(--foreground));
  }
.landing-pricing-card__price-desc {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: clamp(0.9375rem, 2vw, 1.0625rem);
    line-height: 1.55;
    color: oklch(var(--muted-foreground));
    max-width: 36ch;
  }
.landing-pricing-card__features {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: 100%;
    max-width: 360px;
    margin-top: 0.5rem;
  }
.landing-pricing-card__feature {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-family: var(--font-body);
    font-weight: 500;
    font-size: 0.9375rem;
    color: oklch(var(--foreground));
    text-align: left;
  }
.landing-pricing-card__feature::before {
    content: "✓";
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    box-shadow: var(--neomorph-inset-sm);
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    color: oklch(var(--accent));
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.75rem;
    background-color: oklch(var(--background));
  }
.landing-pricing-card__cta {
  touch-action: manipulation;
  border-radius: 1rem;
    box-shadow: var(--neomorph-shadow);
    transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
      cubic-bezier(0.4, 0, 0.2, 1), opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
    contain: layout style;
}
.landing-pricing-card__cta:hover:not(:disabled) {
    box-shadow: var(--neomorph-hover);
    transform: scale(1.02) translateZ(0);
  }
.landing-pricing-card__cta:active:not(:disabled) {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.98) translateZ(0);
  }
.landing-pricing-card__cta:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
  }
.landing-pricing-card__cta:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
.landing-pricing-card__cta {
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    min-height: 44px;
    min-width: 44px;
  }
.landing-pricing-card__cta:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
    border-radius: inherit;
  }
@media (prefers-reduced-motion: reduce) {

  .landing-pricing-card__cta {
    transition: none;
    transform: none;
  }
}
.landing-pricing-card__cta {
    background-color: var(--accent-hex);
    color: #ffffff;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.9375rem;
    padding: 0.875rem 2rem;
    min-height: 52px;
    width: 100%;
    max-width: 320px;
    margin-top: 0.5rem;
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.4), 0 8px 24px
      rgba(var(--accent-rgb), 0.35), 0 0 22px oklch(var(--accent) / 0.5);
    transition: box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1), transform 250ms
      cubic-bezier(0.4, 0, 0.2, 1);
  }
.landing-pricing-card__cta:hover {
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.55), 0 10px 28px
      rgba(var(--accent-rgb), 0.42), 0 0 26px oklch(var(--accent) / 0.6);
    transform: translateY(-2px) translateZ(0);
  }
.landing-pricing-card__cta:active {
    box-shadow: var(--neomorph-pressed);
    transform: translateY(0) translateZ(0);
  }
.landing-pricing-card__note {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.8125rem;
    line-height: 1.5;
    color: oklch(var(--muted-foreground) / 0.85);
    max-width: 40ch;
    margin-top: 0.25rem;
  }
/* ─── Reduced motion guard for extended landing ────────────────────────────
      Disable transitions for users who prefer reduced motion. Content appears
      instantly. Mirrors the existing landing reduced-motion guard. */
@media (prefers-reduced-motion: reduce) {
    .landing-nav,
    .landing-nav__cta,
    .landing-feature-card,
    .landing-pricing-card__cta {
      transition: none;
    }
  }
/* ─── Enhanced Landing Page v2 — additive classes ─────────────────────────
      Refined phone mockup, hero loop animation, install-step animation,
      sticky mobile CTA, "Hoe het werkt" 3-step section, refined RPE scale,
      and feature-row icons. Reuses ONLY existing tokens
      (--accent-hex, --accent-rgb, --accent-dim, --neomorph-*, --font-display,
      --font-body, --background, --card, --foreground, --muted-foreground,
      --border). No existing tokens modified. Accent EXCLUSIVELY #E8630A. */
/* 1. Refined phone mockup — deeper neumorphic shadows + frame detail */
.landing-phone--enhanced {
    position: relative;
    width: clamp(220px, 70vw, 300px);
    aspect-ratio: 9 / 19;
    border-radius: 2.5rem;
    background: oklch(var(--card));
    box-shadow:
      0 2px 4px rgba(0, 0, 0, 0.4),
      0 24px 48px rgba(0, 0, 0, 0.55),
      0 48px 96px rgba(0, 0, 0, 0.45),
      inset 1px 1px 2px rgba(255, 255, 255, 0.06),
      inset -1px -1px 2px rgba(0, 0, 0, 0.6);
    padding: 0.625rem 0.5rem 0.75rem;
    overflow: hidden;
  }
.landing-phone__frame-detail {
    position: absolute;
    pointer-events: none;
  }
.landing-phone__frame-detail--notch {
    top: 0.5rem;
    left: 50%;
    transform: translateX(-50%);
    width: 38%;
    height: 1.25rem;
    border-radius: 0 0 0.875rem 0.875rem;
    background: oklch(0.12 0 0);
    box-shadow: inset 0 -1px 2px rgba(0, 0, 0, 0.8);
  }
.landing-phone__frame-detail--button-l,
  .landing-phone__frame-detail--button-r {
    top: 22%;
    width: 0.1875rem;
    height: 3.5rem;
    border-radius: 2px;
    background: oklch(0.18 0 0);
    box-shadow: inset 1px 0 2px rgba(0, 0, 0, 0.7);
  }
.landing-phone__frame-detail--button-l {
    left: -0.125rem;
  }
.landing-phone__frame-detail--button-r {
    right: -0.125rem;
    height: 5.5rem;
  }
/* 2. Hero phone-mockup animation — sets filling → RPE selecting → chart growing */
.landing-phone__screen--animated {
    animation: landing-hero-loop 9s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
@keyframes landing-hero-loop {
    /* Phase 1 (0-33%): workout sets filling */
    0% {
      --landing-anim-phase: 0;
    }
    8% {
      --landing-anim-phase: 1;
    }
    16% {
      --landing-anim-phase: 2;
    }
    24% {
      --landing-anim-phase: 3;
    }
    33% {
      --landing-anim-phase: 4;
    }
    /* Phase 2 (33-66%): RPE scale selecting */
    41% {
      --landing-anim-phase: 5;
    }
    50% {
      --landing-anim-phase: 6;
    }
    58% {
      --landing-anim-phase: 7;
    }
    66% {
      --landing-anim-phase: 8;
    }
    /* Phase 3 (66-100%): overload chart growing */
    74% {
      --landing-anim-phase: 9;
    }
    82% {
      --landing-anim-phase: 10;
    }
    90% {
      --landing-anim-phase: 11;
    }
    100% {
      --landing-anim-phase: 12;
    }
  }
@media (prefers-reduced-motion: reduce) {
    .landing-phone__screen--animated {
      animation: none;
    }
  }
/* 3. Install-steps animation — Safari share-menu opening + Add to Home Screen click */
.landing-install-step--animated {
    animation: landing-install-step 4.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
@keyframes landing-install-step {
    /* Safari share-menu opening (0-50%) */
    0% {
      opacity: 0.4;
      transform: translateY(6px) scale(0.98);
    }
    25% {
      opacity: 1;
      transform: translateY(0) scale(1);
    }
    /* 'Add to Home Screen' clicking (50-100%) */
    50% {
      opacity: 1;
      transform: translateY(0) scale(1);
    }
    75% {
      opacity: 1;
      transform: scale(0.96);
      box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.5);
    }
    100% {
      opacity: 0.4;
      transform: translateY(6px) scale(0.98);
      box-shadow: none;
    }
  }
@media (prefers-reduced-motion: reduce) {
    .landing-install-step--animated {
      animation: none;
    }
  }
/* 4. Sticky mobile CTA — fixed bottom bar, mobile-only, accent background */
.landing-sticky-cta {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    display: none;
    padding: 0.75rem 1rem calc(0.75rem + env(safe-area-inset-bottom));
    background: oklch(var(--card) / 0.92);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border-top: 1px solid oklch(var(--border));
    box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.35);
  }
@media (max-width: 767px) {
    .landing-sticky-cta {
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 0.75rem;
    }
  }
.landing-sticky-cta__button {
    flex: 1;
    max-width: 360px;
    min-height: 52px;
    padding: 0.875rem 1.5rem;
    border: none;
    border-radius: var(--radius);
    background: linear-gradient(
      135deg,
      var(--accent-hex),
      var(--accent-dim, #4a2400)
    );
    color: oklch(var(--accent-foreground));
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.9375rem;
    letter-spacing: 0.01em;
    cursor: pointer;
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.4), 0 8px 24px
      rgba(var(--accent-rgb), 0.35);
    transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 200ms
      cubic-bezier(0.4, 0, 0.2, 1);
  }
.landing-sticky-cta__button:hover {
    transform: translateY(-2px);
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.55), 0 10px 28px
      rgba(var(--accent-rgb), 0.42);
  }
.landing-sticky-cta__button:active {
    transform: translateY(0);
    box-shadow: var(--neomorph-pressed);
  }
/* 5. 'Hoe het werkt' 3-step section */
.landing-how-it-works {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(1.5rem, 4vw, 2.5rem);
    padding: clamp(3rem, 8vw, 5rem) clamp(1rem, 4vw, 2rem);
    max-width: 1120px;
    margin: 0 auto;
  }
.landing-how-it-works__steps {
    display: grid;
    grid-template-columns: 1fr;
    gap: clamp(1.25rem, 4vw, 2rem);
    width: 100%;
  }
@media (min-width: 768px) {
    .landing-how-it-works__steps {
      grid-template-columns: repeat(3, 1fr);
    }
  }
.landing-how-it-works__step {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.875rem;
    padding: clamp(1.25rem, 3vw, 1.75rem);
    background: oklch(var(--card));
    border-radius: 1.25rem;
    box-shadow: var(--neomorph-shadow-sm);
  }
.landing-how-it-works__step-number {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 9999px;
    background: rgba(var(--accent-rgb), 0.14);
    color: var(--accent-hex);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.25rem;
    box-shadow: inset 0 0 0 1px rgba(var(--accent-rgb), 0.3), 0 0 12px
      rgba(var(--accent-rgb), 0.25);
  }
.landing-how-it-works__step-title {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: clamp(1rem, 2.5vw, 1.125rem);
    color: oklch(var(--foreground));
  }
.landing-how-it-works__step-desc {
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 0.875rem;
    line-height: 1.55;
    color: oklch(var(--muted-foreground));
    max-width: 32ch;
  }
/* 6. Refined RPE scale — horizontal flex, gradient light → accent */
.landing-rpe-scale {
    display: flex;
    gap: 0.375rem;
    width: 100%;
    max-width: 320px;
  }
.landing-rpe-segment {
    flex: 1;
    height: 0.5rem;
    border-radius: 9999px;
    background: linear-gradient(
      90deg,
      oklch(var(--muted) / 0.5),
      rgba(var(--accent-rgb), 0.35)
    );
    box-shadow: var(--neomorph-inset-sm);
    transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow 200ms
      cubic-bezier(0.4, 0, 0.2, 1);
  }
.landing-rpe-segment--active {
    background: linear-gradient(
      90deg,
      rgba(var(--accent-rgb), 0.6),
      var(--accent-hex)
    );
    transform: scaleY(1.4);
    box-shadow: var(--neomorph-inset-sm), 0 0 10px rgba(var(--accent-rgb), 0.5);
  }
/* 7. Feature-row icon — accent-tinted neumorphic inset container */
.landing-feature-row__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    flex-shrink: 0;
    border-radius: 0.875rem;
    background: rgba(var(--accent-rgb), 0.1);
    color: var(--accent-hex);
    box-shadow: var(--neomorph-inset-sm);
  }
/* ─── Enhanced Landing v2 — reduced-motion guard ──────────────────────────
      Disable all v2 animations + transitions for reduced-motion users. */
@media (prefers-reduced-motion: reduce) {
    .landing-phone__screen--animated,
    .landing-install-step--animated,
    .landing-sticky-cta__button,
    .landing-rpe-segment {
      animation: none;
      transition: none;
    }
  }
/* Focus States for Accessibility */
.focus-ring:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
    border-radius: inherit;
  }
.will-change-transform {
    will-change: transform;
  }
.will-change-scroll {
    will-change: scroll-position;
  }
.safe-area-inset-top {
    padding-top: env(safe-area-inset-top);
  }
.safe-area-inset-bottom {
    padding-bottom: env(safe-area-inset-bottom);
  }
/* ─── PostWorkoutModal overlay safe-area guard ────────────────────────────
     The shadcn DialogOverlay is `fixed inset-0 z-50 bg-black/50`. When the
     modal closes, the overlay's fade-out animation can race with page
     navigation, leaving a residual semi-transparent overlay over the status
     bar (which only has body hex bg, not covered by HomePage's fixed oklch
     container). This override makes the overlay start BELOW the
     safe-area-inset-top so the status bar region always shows the themed
     background, never the overlay's bg-black/50. Applied globally to all
     Radix Dialog/Sheet/Drawer overlays as defense-in-depth — every modal
     should respect the status bar safe area in a PWA. */
[data-slot="dialog-overlay"],
  [data-slot="sheet-overlay"],
  [data-slot="drawer-overlay"] {
    top: env(safe-area-inset-top) !important;
  }
/* Plan accent color utilities */
/* Optimized fade transitions */
@keyframes fade-in-50 {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
.fade-in-50 {
    animation: fade-in-50 400ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: opacity;
  }
/* Zoom animation for modals */
@keyframes zoom-in-95 {
    from {
      transform: scale(0.95) translateZ(0);
      opacity: 0;
    }
    to {
      transform: scale(1) translateZ(0);
      opacity: 1;
    }
  }
.zoom-in-95 {
    animation: zoom-in-95 400ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform, opacity;
  }
/* Neumorphic shimmer animation for loading states */
@keyframes neomorph-shimmer {
    0% {
      background-position: -200% 0;
    }
    100% {
      background-position: 200% 0;
    }
  }
.neomorph-shimmer {
    background: linear-gradient(
      90deg,
      oklch(var(--muted) / 0.3) 0%,
      oklch(var(--muted) / 0.5) 50%,
      oklch(var(--muted) / 0.3) 100%
    );
    background-size: 200% 100%;
    animation: neomorph-shimmer 1.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
/* Accent Glow — Buddy-tab inspired card styling: subtle orange radial glow in top-right corner */
.accent-glow {
    position: relative;
    overflow: hidden;
  }
.accent-glow::before {
    content: "";
    position: absolute;
    top: -40px;
    right: -40px;
    width: 120px;
    height: 120px;
    border-radius: 50%;
    background: radial-gradient(
      circle,
      oklch(var(--accent) / 0.1) 0%,
      transparent 70%
    );
    pointer-events: none;
    z-index: 0;
    transform: translateZ(0);
  }
/* Trained Exercise Card Accent — left border + subtle glow for exercises performed this month */
.accent-glow-trained {
    position: relative;
    border-left: 4px solid oklch(var(--accent));
  }
.accent-glow-trained::before {
    content: "";
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: inherit;
    box-shadow: inset 0 0 20px oklch(var(--accent) / 0.08);
    pointer-events: none;
    z-index: 0;
  }
.accent-glow-trained::after {
    content: "";
    position: absolute;
    top: -20px;
    left: -20px;
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: radial-gradient(
      circle,
      oklch(var(--accent) / 0.15) 0%,
      transparent 70%
    );
    pointer-events: none;
    z-index: 0;
  }
/* Dark theme adjustments for trained accent — subtler glow */
.dark .accent-glow-trained {
    border-left: 4px solid oklch(var(--accent));
  }
.dark .accent-glow-trained::before {
    box-shadow: inset 0 0 14px oklch(var(--accent) / 0.08);
  }
.dark .accent-glow-trained::after {
    background: radial-gradient(
      circle,
      oklch(var(--accent) / 0.13) 0%,
      transparent 70%
    );
  }
/* Tooltip Styles */
.tooltip {
  border-radius: var(--radius);
  background-color: oklch(var(--popover));
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 500;
  color: oklch(var(--popover-foreground));
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .tooltip {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .tooltip {
    border: 1px solid oklch(var(--border));
  }
}
.tooltip {
    box-shadow: var(--neomorph-shadow-lg);
    z-index: 9999;
  }
/* ─── Light-theme search input fix (multi-layer override) ─────────────────
     These rules ensure search bars are always light with dark text in the
     light theme, regardless of CSS variable inheritance or specificity issues. */
:root .exercises-search-input,
  :root input.exercises-search-input {
    background-color: #f0edea !important;
    color: #1a1a1a !important;
    caret-color: #1a1a1a !important;
  }
:root .exercises-search-input::-moz-placeholder {
    color: #888888 !important;
    opacity: 1 !important;
  }
:root .exercises-search-input::placeholder {
    color: #888888 !important;
    opacity: 1 !important;
  }
:root .history-search-input,
  :root input.history-search-input {
    background-color: #f0edea !important;
    color: #1a1a1a !important;
    caret-color: #1a1a1a !important;
  }
:root .history-search-input::-moz-placeholder {
    color: #888888 !important;
    opacity: 1 !important;
  }
:root .history-search-input::placeholder {
    color: #888888 !important;
    opacity: 1 !important;
  }
/* Dark theme must remain unchanged — restore dark values */
.dark .exercises-search-input,
  .dark input.exercises-search-input,
  .dark .history-search-input,
  .dark input.history-search-input {
    background-color: oklch(var(--input)) !important;
    color: oklch(var(--foreground)) !important;
    caret-color: oklch(var(--foreground)) !important;
  }
.dark .exercises-search-input::-moz-placeholder, .dark .history-search-input::-moz-placeholder {
    color: oklch(var(--muted-foreground)) !important;
    opacity: 1 !important;
  }
.dark .exercises-search-input::placeholder,
  .dark .history-search-input::placeholder {
    color: oklch(var(--muted-foreground)) !important;
    opacity: 1 !important;
  }
/* ─────────────────────────────────────────────────────────────────────────── */
/* ═══════════════════════════════════════════════════════════════════════════
     FASE 2 — ACHIEVEMENT REVEAL
     Card-flip reveal sequence, rarity hierarchy, celebration moments, countdown
     ring, and haptic-style visual feedback. ALL classes here reuse the existing
     neumorphic + accent tokens (--accent, --accent-hex, --accent-rgb,
     --accent-dim, --neomorph-shadow-*, --neomorph-inset, --neomorph-pressed)
     and work in both :root (light) and .dark themes via the inherited variables.
     No existing tokens are modified — this block is purely additive.
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── 3D card-flip foundation ───────────────────────────────────────────────
     The reveal card is a .reveal-card wrapper with perspective; the inner
     .reveal-card-inner carries the rotateY transform. .is-revealed flips it.
     backface-visibility hides the back face once flipped. transform-style:
     preserve-3d keeps the two faces in the same 3D space. */
.reveal-card {
    perspective: 1200px;
    -webkit-perspective: 1200px;
  }
.reveal-card.is-revealed .reveal-card-inner {
    transform: rotateY(180deg);
  }
/* Pre-reveal back face: a sealed neumorphic card with a question-mark motif.
     Uses the existing neomorphic raised shadow + accent ring. */
/* ─── Staggered reveal delays (150ms increments) ────────────────────────────
     Applied to .reveal-card to delay the flip start; the 6th step caps a
     6-card batch. Higher indexes wait longer so cards flip in sequence. */
.reveal-delay-1 {
    transition-delay: 0ms;
  }
.reveal-delay-2 {
    transition-delay: 150ms;
  }
.reveal-delay-3 {
    transition-delay: 300ms;
  }
.reveal-delay-4 {
    transition-delay: 450ms;
  }
.reveal-delay-5 {
    transition-delay: 600ms;
  }
.reveal-delay-6 {
    transition-delay: 750ms;
  }
/* ─── Haptic-style visual feedback (scale pulse on flip completion) ─────────
     A short scale pulse plays when a card finishes flipping, simulating a
     haptic "thunk". Applied alongside .is-revealed via the .reveal-pulse
     helper. */
@keyframes reveal-scale-pulse {
    0% {
      transform: rotateY(180deg) scale(1);
    }
    40% {
      transform: rotateY(180deg) scale(1.04);
    }
    100% {
      transform: rotateY(180deg) scale(1);
    }
  }
/* ─── Rarity visual hierarchy ───────────────────────────────────────────────
     Four tiers, escalating accent intensity. All reuse --accent / --accent-hex
     / --accent-rgb so a single token change re-tints the whole hierarchy. */
/* COMMON — subtle ring only, no glow. Recessive tier. */
.rarity-common {
    box-shadow: var(--neomorph-shadow), 0 0 0 1px oklch(var(--border) / 0.6);
  }
/* RARE — accent ring, no glow. The accent first appears. */
.rarity-rare {
    box-shadow: var(--neomorph-shadow), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.45);
  }
/* EPIC — accent glow (radial corner) + shimmer sweep. */
.rarity-epic {
    position: relative;
    box-shadow: var(--neomorph-shadow-lg), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.6), 0 0 18px rgba(var(--accent-rgb), 0.25);
  }
.rarity-epic::after {
    content: "";
    position: absolute;
    top: -40px;
    right: -40px;
    width: 120px;
    height: 120px;
    border-radius: 50%;
    background: radial-gradient(
      circle,
      rgba(var(--accent-rgb), 0.22) 0%,
      transparent 70%
    );
    pointer-events: none;
    z-index: 0;
  }
.rarity-epic .reveal-shimmer {
    background: linear-gradient(
      110deg,
      transparent 0%,
      transparent 40%,
      rgba(var(--accent-rgb), 0.18) 50%,
      transparent 60%,
      transparent 100%
    );
    background-size: 250% 100%;
    animation: achievement-shimmer 2.4s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
/* LEGENDARY — accent-glow-trained left border + pulsing accent glow. The
     apex tier; the only rarity with continuous motion. */
.rarity-legendary {
    position: relative;
    border-left: 4px solid oklch(var(--accent));
    box-shadow: var(--neomorph-shadow-xl), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.7), 0 0 26px rgba(var(--accent-rgb), 0.4);
    animation: legendary-pulse 2.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
.rarity-legendary::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: inset 0 0 22px rgba(var(--accent-rgb), 0.12);
    pointer-events: none;
    z-index: 0;
  }
.rarity-legendary::after {
    content: "";
    position: absolute;
    top: -24px;
    left: -24px;
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background: radial-gradient(
      circle,
      rgba(var(--accent-rgb), 0.28) 0%,
      transparent 70%
    );
    pointer-events: none;
    z-index: 0;
    animation: legendary-glow 2.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
/* Dark-theme tuning: subtler glow so legendary doesn't blow out on near-black. */
.dark .rarity-epic {
    box-shadow: var(--neomorph-shadow-lg), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.55), 0 0 14px rgba(var(--accent-rgb), 0.2);
  }
.dark .rarity-epic::after {
    background: radial-gradient(
      circle,
      rgba(var(--accent-rgb), 0.18) 0%,
      transparent 70%
    );
  }
.dark .rarity-legendary {
    box-shadow: var(--neomorph-shadow-xl), 0 0 0 1.5px
      rgba(var(--accent-rgb), 0.65), 0 0 20px rgba(var(--accent-rgb), 0.32);
  }
.dark .rarity-legendary::before {
    box-shadow: inset 0 0 16px rgba(var(--accent-rgb), 0.1);
  }
.dark .rarity-legendary::after {
    background: radial-gradient(
      circle,
      rgba(var(--accent-rgb), 0.22) 0%,
      transparent 70%
    );
  }
/* ─── Rarity badges ─────────────────────────────────────────────────────────
     Small pill labels. Color intensity escalates with rarity. */
.rarity-badge {
  display: inline-flex;
  align-items: center;
  border-radius: 9999px;
  padding-left: 0.625rem;
  padding-right: 0.625rem;
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  letter-spacing: 0.025em;
    font-family: var(--font-display);
}
.rarity-badge--common {
    background-color: oklch(var(--muted));
    color: oklch(var(--muted-foreground));
  }
.rarity-badge--rare {
    background-color: rgba(var(--accent-rgb), 0.16);
    color: oklch(var(--accent));
  }
.rarity-badge--epic {
    background-color: rgba(var(--accent-rgb), 0.22);
    color: oklch(var(--accent));
    box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.3);
  }
.rarity-badge--legendary {
    background-color: rgba(var(--accent-rgb), 0.28);
    color: oklch(var(--accent));
    box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.45);
    animation: legendary-pulse 2.2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
/* ─── NEW indicator (first-time reveal) ─────────────────────────────────────
     A small accent dot in the card corner for achievements seen for the first
     time. */
.reveal-new-indicator {
    position: absolute;
    top: 10px;
    right: 10px;
    width: 8px;
    height: 8px;
    border-radius: 9999px;
    background-color: oklch(var(--accent));
    box-shadow: 0 0 8px rgba(var(--accent-rgb), 0.6);
    z-index: 2;
    animation: new-dot-pulse 1.6s cubic-bezier(0.4, 0, 0.2, 1) infinite;
  }
/* ─── Celebration pulse / glow keyframes ────────────────────────────────────
     Used by legendary rarity and rare reward moments. */
@keyframes legendary-pulse {
    0%,
    100% {
      box-shadow: var(--neomorph-shadow-xl), 0 0 0 1.5px
        rgba(var(--accent-rgb), 0.7), 0 0 26px rgba(var(--accent-rgb), 0.4);
    }
    50% {
      box-shadow: var(--neomorph-shadow-xl), 0 0 0 1.5px
        rgba(var(--accent-rgb), 0.85), 0 0 38px rgba(var(--accent-rgb), 0.6);
    }
  }
@keyframes legendary-glow {
    0%,
    100% {
      opacity: 0.7;
      transform: scale(1);
    }
    50% {
      opacity: 1;
      transform: scale(1.12);
    }
  }
@keyframes new-dot-pulse {
    0%,
    100% {
      opacity: 1;
      transform: scale(1);
    }
    50% {
      opacity: 0.6;
      transform: scale(1.3);
    }
  }
/* Celebration burst — a one-shot radial flash played when a legendary/epic
     card flips. Applied to a transparent overlay element inside the card. */
@keyframes celebration-burst {
    0% {
      opacity: 0;
      transform: scale(0.6);
    }
    35% {
      opacity: 0.8;
      transform: scale(1.4);
    }
    100% {
      opacity: 0;
      transform: scale(2.2);
    }
  }
/* Achievement shimmer sweep (used by epic rarity .reveal-shimmer child). */
@keyframes achievement-shimmer {
    0% {
      background-position: 250% 0;
    }
    100% {
      background-position: -250% 0;
    }
  }
/* ─── Countdown ring (auto-dismiss) ─────────────────────────────────────────
     An SVG circle whose stroke-dashoffset animates from 0 → circumference
      over the auto-dismiss duration (45s — MUST match AUTO_DISMISS_MS in
      PostWorkoutModal.tsx). The ring depletes visually to signal remaining
      time. Pause-on-hover: when the dialog carries data-paused="true" the
      animation freezes via animation-play-state: paused so it stays in sync
      with the JS timer (which is also paused on hover). */
@keyframes countdown-ring-deplete {
    from {
      stroke-dashoffset: 0;
    }
    to {
      stroke-dashoffset: var(--countdown-circumference, 188.5);
    }
  }
.countdown-ring__progress {
    fill: none;
    stroke: oklch(var(--accent));
    stroke-width: 3;
    stroke-linecap: round;
    animation: countdown-ring-deplete 45s linear forwards;
  }
/* Pause the countdown ring when the dialog is hovered — keeps the visual
     ring in lockstep with the paused JS close timer. */
[data-paused="true"] .countdown-ring__progress {
    animation-play-state: paused;
  }
.countdown-ring__track {
    fill: none;
    stroke: oklch(var(--muted));
    stroke-width: 3;
    opacity: 0.4;
  }
/* ─── Reveal overlay container ──────────────────────────────────────────────
     The full-screen overlay that hosts the reveal grid. Builds on the existing
     neomorphic + accent tokens; uses bg-background so it inherits theme. */
/* ─── AchievementsPage grid states ──────────────────────────────────────────
     Revealed = full color + accent-glow; unrevealed = grayscale + ??? lock.
     Reuses the existing .accent-glow utility for revealed cards. */
.achievement-card--locked {
    filter: grayscale(1);
    opacity: 0.55;
  }
.achievement-card--locked .achievement-card__icon,
  .achievement-card--locked .achievement-card__title,
  .achievement-card--locked .achievement-card__description {
    filter: blur(2px);
    -webkit-user-select: none;
       -moz-user-select: none;
            user-select: none;
  }
.achievement-card__placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
    font-family: var(--font-display);
    color: oklch(var(--muted-foreground));
    letter-spacing: 0.1em;
}
/* ─── Filter bar pills (AchievementsPage) ───────────────────────────────────
     Reuses .neomorph-button base; active state gets accent ring + tint. */
.filter-pill {
  border-radius: 9999px;
  background-color: oklch(var(--background));
  padding-left: 1rem;
  padding-right: 1rem;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 500;
    box-shadow: var(--neomorph-shadow);
    transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
      cubic-bezier(0.4, 0, 0.2, 1), opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
    contain: layout style;
}
.filter-pill:hover:not(:disabled) {
    box-shadow: var(--neomorph-hover);
    transform: scale(1.02) translateZ(0);
  }
.filter-pill:active:not(:disabled) {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.98) translateZ(0);
  }
.filter-pill:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
  }
.filter-pill:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
@media (prefers-reduced-motion: reduce) {

  .filter-pill {
    transition: none;
    transform: none;
  }
}
.filter-pill {
    color: oklch(var(--muted-foreground));
  }
.filter-pill.is-active {
    background-color: rgba(var(--accent-rgb), 0.14);
    color: oklch(var(--accent));
    box-shadow: var(--neomorph-shadow), 0 0 0 1.5px rgba(var(--accent-rgb), 0.5);
  }
/* ─── Statistics header (AchievementsPage) ──────────────────────────────────
     Mini rarity-distribution bar. Each segment uses the rarity's accent
     intensity so the chart doubles as a rarity legend. */
.rarity-bar {
  display: flex;
  height: 0.5rem;
  width: 100%;
  overflow: hidden;
  border-radius: 9999px;
    background-color: oklch(var(--muted) / 0.4);
}
.rarity-bar__segment--common {
    background-color: oklch(var(--muted-foreground) / 0.5);
  }
.rarity-bar__segment--rare {
    background-color: rgba(var(--accent-rgb), 0.45);
  }
.rarity-bar__segment--epic {
    background-color: rgba(var(--accent-rgb), 0.7);
  }
.rarity-bar__segment--legendary {
    background-color: oklch(var(--accent));
    box-shadow: 0 0 6px rgba(var(--accent-rgb), 0.5);
  }
/* ═══════════════════════════════════════════════════════════════════════════
     FASE 6 — BUDDY KUDOS
     Strava-style kudos from the buddy activity feed: one kudos per buddy per
     workout. All classes reuse existing neumorphic + accent tokens
     (--accent, --accent-hex, --accent-rgb, --accent-dim, --neomorph-shadow,
     --neomorph-pressed, --neomorph-hover) and work in both :root (light) and
     .dark themes via inherited variables. NO new keyframes or animations —
     native feel only (subtle 200ms box-shadow transitions inherited from
     .neomorph-button). No existing tokens are modified; this block is purely
     additive.
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Kudos button ─────────────────────────────────────────────────────────
      Compact 44px touch-target button hosting a heart/thumbs-up icon. Default
      state = recessed neumorphic-button (raised). Active state (.is-active) =
      filled accent with .neomorph-accent glow (Strava-style). One kudos per
      buddy per workout — disabled state (.is-disabled) greys out and locks. */
.kudos-button {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow);
    transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
      cubic-bezier(0.4, 0, 0.2, 1), opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
    contain: layout style;
}
.kudos-button:hover:not(:disabled) {
    box-shadow: var(--neomorph-hover);
    transform: scale(1.02) translateZ(0);
  }
.kudos-button:active:not(:disabled) {
    box-shadow: var(--neomorph-pressed);
    transform: scale(0.98) translateZ(0);
  }
.kudos-button:focus-visible {
    outline: 2px solid oklch(var(--accent));
    outline-offset: 2px;
  }
.kudos-button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
@media (prefers-reduced-motion: reduce) {

  .kudos-button {
    transition: none;
    transform: none;
  }
}
.kudos-button {
    width: 44px;
    height: 44px;
    padding: 0;
    color: oklch(var(--muted-foreground));
    contain: layout style;
  }
.kudos-button.is-active {
    box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.16), -4px -4px 10px
      rgba(255, 255, 255, 0.9), 0 0 22px oklch(var(--accent) / 0.5);
    transition: box-shadow 400ms cubic-bezier(0.4, 0, 0.2, 1), transform 400ms
      cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
  }
.kudos-button.is-active:hover {
    box-shadow: 5px 5px 12px rgba(0, 0, 0, 0.18), -5px -5px 12px
      rgba(255, 255, 255, 0.95), 0 0 26px oklch(var(--accent) / 0.6);
    transform: scale(1.02) translateZ(0);
  }
.dark .kudos-button.is-active {
    box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.45), -4px -4px 8px
      rgba(255, 255, 255, 0.04), 0 0 16px oklch(var(--accent) / 0.4);
  }
.dark .kudos-button.is-active:hover {
    box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.52), -5px -5px 10px
      rgba(255, 255, 255, 0.05), 0 0 18px oklch(var(--accent) / 0.48);
    transform: scale(1.02) translateZ(0);
  }
.kudos-button.is-active {
    background-color: var(--accent-dim);
    color: var(--accent-hex);
  }
.dark .kudos-button.is-active {
    background-color: rgba(var(--accent-rgb), 0.18);
    color: oklch(var(--accent));
  }
.kudos-button.is-disabled,
  .kudos-button:disabled {
    opacity: 0.45;
    cursor: not-allowed;
    box-shadow: var(--neomorph-shadow-sm);
  }
/* ─── Kudos count badge ────────────────────────────────────────────────────
      Orange pill showing total kudos received. Reuses the established orange
      badge pattern: bg-accent, text-[10px], font-bold, text-accent-foreground,
      rounded-full. Sits next to the kudos button or on a feed card header. */
.kudos-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background-color: oklch(var(--accent));
  padding-left: 0.5rem;
  padding-right: 0.5rem;
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
  font-size: 10px;
  font-weight: 700;
  color: oklch(var(--accent-foreground));
    min-width: 20px;
    height: 18px;
    line-height: 1;
    letter-spacing: 0.02em;
    box-shadow: 0 0 8px rgba(var(--accent-rgb), 0.35);
}
.kudos-badge.is-zero {
    background-color: oklch(var(--muted));
    color: oklch(var(--muted-foreground));
    box-shadow: none;
  }
/* ─── Buddy activity feed card ─────────────────────────────────────────────
      Variant of the standard .neomorph card for the buddy activity feed. Adds
      a subtle accent ring on the left edge when the workout has received
      kudos from the current user (visual cue for "already kudos'd"). Layout:
      avatar + buddy name + workout summary + kudos button + count badge. */
.kudos-feed-card {
  border-radius: 1rem;
  background-color: oklch(var(--background));
  padding: 1rem;
    box-shadow: var(--neomorph-shadow), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .kudos-feed-card {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .kudos-feed-card {
    border: 1px solid oklch(var(--border));
  }
}
.kudos-feed-card {
    position: relative;
  }
.kudos-feed-card.is-kudosd {
    border-left: 3px solid oklch(var(--accent));
    padding-left: calc(1rem - 3px);
  }
.dark .kudos-feed-card.is-kudosd {
    border-left: 3px solid oklch(var(--accent));
  }
/* Avatar slot inside the feed card — round neumorph-sm recessed circle. */
.kudos-feed-card__avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  background-color: oklch(var(--background));
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .kudos-feed-card__avatar {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .kudos-feed-card__avatar {
    border: 1px solid oklch(var(--border));
  }
}
.kudos-feed-card__avatar {
    width: 40px;
    height: 40px;
    flex-shrink: 0;
    color: oklch(var(--muted-foreground));
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 14px;
  }
/* Workout summary line inside the feed card. */
.kudos-feed-card__summary {
  min-width: 0px;
  flex: 1 1 0%;
}
.kudos-feed-card__name {
  font-size: 0.875rem;
  line-height: 1.25rem;
  font-weight: 600;
    color: oklch(var(--foreground));
}
.kudos-feed-card__workout {
  font-size: 0.75rem;
  line-height: 1rem;
    color: oklch(var(--muted-foreground));
}
.kudos-feed-card__meta {
  font-size: 11px;
    color: oklch(var(--muted-foreground) / 0.7);
}
/* Kudos action cluster: button + badge, right-aligned in the card. */
.kudos-feed-card__action {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
    flex-shrink: 0;
}
/* ─── Friends-tab orange badge ─────────────────────────────────────────────
      Small orange dot badge overlaid on the Friends tab in the bottom nav to
      signal pending kudos / new buddy activity. Reuses the orange badge
      pattern (bg-accent, text-[10px], font-bold, text-accent-foreground,
      rounded-full) but smaller — a count pill or a plain dot when count is
      just "new". Positioned absolutely by the parent nav item. */
/* ═══════════════════════════════════════════════════════════════════════════
     FASE 7 — MASTERY METER (per oefening)
     Mastery tab on the Exercise pop-up: a 0-100 mastery score, level name, and
     a round SVG progress ring toward the next level. Reuses existing neumorphic
     + accent tokens (--accent, --accent-hex, --accent-rgb, --accent-dim,
     --neomorph-shadow, --neomorph-inset-sm, --neomorph-shadow-sm) additively.
     The SVG ring mirrors the established challenge/season ring pattern (round, not
     linear bar) — same approach as .countdown-ring (rotate -90deg, round
     stroke-linecap, accent stroke, muted track). Level badge intensity scales
     across 5 tiers (Beginner → Master) via escalating accent tint + glow,
     mirroring the rarity-badge hierarchy. Breakdown rows reuse
     .neomorph-inset-sm recessed surfaces. No existing tokens modified; this
     block is purely additive. The only new motion is a subtle functional
     "calculating" pulse on the score during recalc on tab-open (respects
     prefers-reduced-motion via the global rule above).
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Mastery score card ──────────────────────────────────────────────────
      Hero card hosting the score, ring, and level badge. Builds on .neomorph
      rounded-2xl bg-background with a subtle accent corner glow (reuses
      .accent-glow ::before radial). The score is the focal point — Space
      Grotesk, large, accent-tinted only when fully calculated. */
.mastery-card {
  border-radius: 1rem;
  background-color: oklch(var(--background));
  padding: 1.25rem;
    box-shadow: var(--neomorph-shadow), var(--neomorph-accent-ring);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {

  .mastery-card {
    transition: none;
    transform: none;
  }
}
@media (prefers-contrast: high) {
  .mastery-card {
    border: 1px solid oklch(var(--border));
  }
}
.mastery-card {
    position: relative;
    overflow: hidden;
  }
/* ─── Mastery SVG progress ring ────────────────────────────────────────────
      Round ring (NOT a linear bar) — mirrors .countdown-ring: rotate -90deg so
      the arc starts at 12 o'clock, round stroke-linecap, accent stroke on a
      muted track. The progress is set via stroke-dasharray / stroke-dashoffset
      inline (computed from the score fraction toward next level). The ring
      container is recessed (.neomorph-inset-sm) so the ring sits in a sculpted
      well. Track = muted/40, progress = accent with a soft accent glow. */
.mastery-ring {
    transform: rotate(-90deg);
    transform-origin: center;
  }
.mastery-ring__track {
    fill: none;
    stroke: oklch(var(--muted));
    stroke-width: 8;
    opacity: 0.4;
  }
.mastery-ring__progress {
    fill: none;
    stroke: oklch(var(--accent));
    stroke-width: 8;
    stroke-linecap: round;
    transition: stroke-dashoffset 600ms cubic-bezier(0.4, 0, 0.2, 1);
    filter: drop-shadow(0 0 4px rgba(var(--accent-rgb), 0.35));
  }
.dark .mastery-ring__progress {
    filter: drop-shadow(0 0 3px rgba(var(--accent-rgb), 0.28));
  }
/* Ring container well — recessed neumorphic circle behind the SVG so the
      ring reads as sculpted depth, not a flat sticker. */
.mastery-ring-well {
  border-radius: 9999px;
    box-shadow: var(--neomorph-inset-sm);
    display: flex;
    align-items: center;
    justify-content: center;
}
/* Center score stack — absolutely positioned over the ring well so the
      number sits dead-center inside the ring. */
.mastery-ring-center {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: none;
  }
.mastery-score {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 2.75rem;
    line-height: 1;
    color: oklch(var(--foreground));
    letter-spacing: -0.02em;
  }
.mastery-level-name {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 0.875rem;
    color: oklch(var(--accent));
    margin-top: 4px;
    letter-spacing: 0.02em;
  }
/* ─── Level badge — intensity scaling across 5 tiers ──────────────────────
      Mirrors the .rarity-badge--* hierarchy: same pill shape, escalating
      accent tint + glow from Beginner (dimmest) to Master (full accent).
      Intensity scales via background alpha, text color, and box-shadow glow. */
.mastery-level-badge {
  display: inline-flex;
  align-items: center;
  border-radius: 9999px;
  padding-left: 0.625rem;
  padding-right: 0.625rem;
  padding-top: 0.125rem;
  padding-bottom: 0.125rem;
  font-size: 0.75rem;
  line-height: 1rem;
  font-weight: 600;
  letter-spacing: 0.025em;
    font-family: var(--font-display);
}
/* Beginner — most recessive: muted bg, muted-foreground text, no glow */
.mastery-level-badge--beginner {
    background-color: oklch(var(--muted));
    color: oklch(var(--muted-foreground));
  }
/* Novice — faint accent tint, accent text, no glow */
.mastery-level-badge--novice {
    background-color: rgba(var(--accent-rgb), 0.1);
    color: oklch(var(--accent));
  }
/* Intermediate — moderate accent tint, subtle ring */
.mastery-level-badge--intermediate {
    background-color: rgba(var(--accent-rgb), 0.16);
    color: oklch(var(--accent));
    box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.25);
  }
/* Advanced — stronger tint + soft glow */
.mastery-level-badge--advanced {
    background-color: rgba(var(--accent-rgb), 0.22);
    color: oklch(var(--accent));
    box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.3);
  }
/* Master — full accent, brightest glow (apex tier) */
.mastery-level-badge--master {
    background-color: rgba(var(--accent-rgb), 0.28);
    color: oklch(var(--accent));
    box-shadow: 0 0 14px rgba(var(--accent-rgb), 0.45);
  }
/* ─── Breakdown list rows ──────────────────────────────────────────────────
      Each row is a recessed .neomorph-inset-sm surface with a label, a score
      chip, and a thin mini segment bar whose orange fill intensity matches the
      factor's contribution. Reuses the rarity-bar segment intensity pattern. */
.mastery-breakdown-row {
  border-radius: 0.75rem;
  padding-left: 0.75rem;
  padding-right: 0.75rem;
  padding-top: 0.625rem;
  padding-bottom: 0.625rem;
    box-shadow: var(--neomorph-inset-sm);
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.mastery-breakdown-row__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
  }
.mastery-breakdown-row__label {
    font-family: var(--font-body);
    font-size: 0.8125rem;
    font-weight: 500;
    color: oklch(var(--foreground) / 0.88);
  }
.mastery-breakdown-row__value {
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 600;
    color: oklch(var(--muted-foreground));
    letter-spacing: 0.01em;
  }
/* Mini segment bar — thin (4px) rounded track with an accent fill whose
      width = the factor's percentage. Fill intensity scales with the value:
      low scores use a dimmer accent, high scores use full accent + glow. */
.mastery-breakdown-bar {
  display: flex;
  height: 0.25rem;
  width: 100%;
  overflow: hidden;
  border-radius: 9999px;
    background-color: oklch(var(--muted) / 0.4);
}
.mastery-breakdown-bar__fill {
    background-color: oklch(var(--accent));
    border-radius: 9999px;
    transition: width 500ms cubic-bezier(0.4, 0, 0.2, 1);
  }
/* Low-contribution fill (< 40%) — dimmer accent, no glow */
.mastery-breakdown-bar__fill--low {
    background-color: rgba(var(--accent-rgb), 0.45);
  }
/* Mid-contribution fill (40-70%) — accent, no glow */
.mastery-breakdown-bar__fill--mid {
    background-color: oklch(var(--accent));
  }
/* High-contribution fill (> 70%) — accent + soft glow */
.mastery-breakdown-bar__fill--high {
    background-color: oklch(var(--accent));
    box-shadow: 0 0 6px rgba(var(--accent-rgb), 0.5);
  }
/* ─── Calculating indicator ────────────────────────────────────────────────
      A subtle functional pulse shown on the score while the mastery is being
      recalculated on tab-open. The ONLY new motion in this block — mirrors
      the user preference for "no fancy custom UI, no animaties" with the
      explicit exception that a subtle pulse during recalc is functional.
      Respects prefers-reduced-motion via the global rule at the bottom of this
      file. */
.mastery-calculating .mastery-score {
    animation: mastery-calculating-pulse 1.2s cubic-bezier(0.4, 0, 0.2, 1)
      infinite;
  }
.mastery-calculating-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 9999px;
    background-color: oklch(var(--accent));
    box-shadow: 0 0 6px rgba(var(--accent-rgb), 0.5);
    animation: mastery-calculating-pulse 1.2s cubic-bezier(0.4, 0, 0.2, 1)
      infinite;
  }
@keyframes mastery-calculating-pulse {
    0%,
    100% {
      opacity: 0.55;
    }
    50% {
      opacity: 1;
    }
  }
/* ═══════════════════════════════════════════════════════════════════════════
     FASE 3 STATS — Fatigue vs Fitness + Push/Pull/Legs donut + Overload nav
     Additive utilities (Phase: Fase 3 Stats tab upgrade). Reuses existing
     --accent-hex / --accent-rgb / --neomorph-shadow / --neomorph-inset-sm
     tokens plus the new --ff-* / --ppl-* / --ol-* tokens defined above. Mirrors
     the .mw-* Fase 1 block structure for consistency: KPI cards (inset well),
     gradient fills under chart lines, TSB indicator, color-coded alert box,
     donut ring well + arc glow + in-ring percentage labels, nav-card + sparkline
     preview area. All classes are additive — no existing classes or tokens
     modified.
     ═══════════════════════════════════════════════════════════════════════════ */
/* ─── KPI card (Fitness / Vermoeidheid value card) ───────────────────────────
     Neumorphic raised card (rounded-xl) hosting an icon + label + value + trend
     pijl. The value sits inside an inset well (--ff-kpi-well) so it reads as a
     sculpted recess — same depth language as .mw-ring-well / .wq-ring-well.
     Padding matches .mw-insight for visual rhythm. */
.ff-kpi {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem 0.875rem;
    border-radius: 0.75rem;
    background-color: oklch(var(--card));
    box-shadow: var(--neomorph-shadow-sm);
    overflow: hidden;
  }
/* KPI header row — icon + label left, trend pijl right. */
.ff-kpi__header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
  }
/* KPI icon — small square (28px) accent-tinted background with colored icon.
     Color driven by --ff-kpi-rgb set on the card root (fitness=blauw,
     fatigue=rood). Mirrors .mw-insight__icon shape. */
.ff-kpi__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background-color: rgba(var(--ff-kpi-rgb, var(--accent-rgb)), 0.14);
    color: rgb(var(--ff-kpi-rgb, var(--accent-rgb)));
    flex-shrink: 0;
  }
/* KPI label — tiny uppercase letter-spaced muted. */
.ff-kpi__label {
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: oklch(var(--muted-foreground));
    line-height: 1;
    flex: 1 1 auto;
    min-width: 0;
  }
/* KPI trend pijl — small ↑/↓/→ indicator + delta value. Color reflects
     direction: green for positive fitness / reduced fatigue, red for negative. */
.ff-kpi__trend {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    font-family: var(--font-display);
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 1;
    flex-shrink: 0;
  }
.ff-kpi__trend--up {
    color: rgb(var(--ff-alert-green-rgb));
  }
.ff-kpi__trend--down {
    color: rgb(var(--ff-alert-red-rgb));
  }
.ff-kpi__trend--flat {
    color: oklch(var(--muted-foreground));
  }
/* KPI value well — inset recess hosting the big number. Mirrors .mw-ring-well
     / .wq-ring-well depth language (rectangular, rounded-lg). */
.ff-kpi__value-well {
    display: flex;
    align-items: baseline;
    gap: 0.25rem;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    background-color: oklch(var(--background));
    box-shadow: var(--ff-kpi-well);
  }
.ff-kpi__value {
    font-family: var(--font-display);
    font-size: 1.25rem;
    font-weight: 700;
    color: oklch(var(--foreground));
    line-height: 1.1;
    letter-spacing: -0.01em;
  }
.ff-kpi__unit {
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 500;
    color: oklch(var(--muted-foreground));
    line-height: 1;
  }
/* ─── Fatigue vs Fitness chart gradient fills ───────────────────────────────
     Applied to the SVG <defs> linearGradient stops under the ATL (fitness) and
     CTL (fatigue) lines. The gradient fades from the line color (top, opaque)
     to transparent (bottom) so the fill reads as a soft area under the curve.
     Stop colors read --ff-fitness-rgb / --ff-fatigue-rgb via CSS vars set on
     the gradient element (or inherited from the chart root). */
.ff-fill-fitness {
    stop-color: rgb(var(--ff-fitness-rgb));
    stop-opacity: 0.32;
  }
.ff-fill-fitness--bottom {
    stop-color: rgb(var(--ff-fitness-rgb));
    stop-opacity: 0;
  }
.ff-fill-fatigue {
    stop-color: rgb(var(--ff-fatigue-rgb));
    stop-opacity: 0.28;
  }
.ff-fill-fatigue--bottom {
    stop-color: rgb(var(--ff-fatigue-rgb));
    stop-opacity: 0;
  }
/* Chart line stroke classes — applied to the ATL/CTL <path> elements so the
     line colors match the gradient fills. */
.ff-line-fitness {
    stroke: rgb(var(--ff-fitness-rgb));
  }
.ff-line-fatigue {
    stroke: rgb(var(--ff-fatigue-rgb));
  }
/* ─── TSB (Training Stress Balance) indicator ───────────────────────────────
     Compact pill showing the TSB value with a color-coded dot. Color reflects
     the zone: green (fresh, TSB > +5), amber (moderate, -10..+5), red
     (overtrained, < -10). Reuses the .ff-alert-* tokens. */
.ff-tsb {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.375rem 0.75rem;
    border-radius: 9999px;
    background-color: oklch(var(--card));
    box-shadow: var(--neomorph-shadow-sm);
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 600;
    color: oklch(var(--foreground));
    line-height: 1;
  }
/* TSB zone dot — small 8px circle, color reflects the zone. */
.ff-tsb__dot {
    width: 8px;
    height: 8px;
    border-radius: 9999px;
    flex-shrink: 0;
  }
.ff-tsb--fresh .ff-tsb__dot {
    background-color: oklch(var(--ff-alert-green));
    box-shadow: 0 0 6px rgba(var(--ff-alert-green-rgb), 0.5);
  }
.ff-tsb--moderate .ff-tsb__dot {
    background-color: oklch(var(--ff-alert-amber));
    box-shadow: 0 0 6px rgba(var(--ff-alert-amber-rgb), 0.5);
  }
.ff-tsb--overtrained .ff-tsb__dot {
    background-color: oklch(var(--ff-alert-red));
    box-shadow: 0 0 6px rgba(var(--ff-alert-red-rgb), 0.5);
  }
/* ─── Color-coded alert box (rule-based recommendation) ──────────────────────
     Neumorphic raised card with a colored left border + tinted icon + header +
     body. Color reflects the recommendation zone (green/amber/red). Mirrors
     .mw-insight structure but with zone-driven color instead of fixed accent. */
.ff-alert {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.625rem;
    padding: 0.75rem 0.875rem;
    border-radius: 0.75rem;
    background-color: oklch(var(--card));
    box-shadow: var(--neomorph-shadow-sm);
    border-left: 3px solid oklch(var(--ff-alert-color, var(--accent)));
    overflow: hidden;
  }
.ff-alert--fresh {
    --ff-alert-color: var(--ff-alert-green);
    --ff-alert-rgb: var(--ff-alert-green-rgb);
  }
.ff-alert--moderate {
    --ff-alert-color: var(--ff-alert-amber);
    --ff-alert-rgb: var(--ff-alert-amber-rgb);
  }
.ff-alert--overtrained {
    --ff-alert-color: var(--ff-alert-red);
    --ff-alert-rgb: var(--ff-alert-red-rgb);
  }
/* Alert icon — small square (28px) zone-tinted background with zone-colored icon. */
.ff-alert__icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background-color: rgba(var(--ff-alert-rgb, var(--accent-rgb)), 0.14);
    color: oklch(var(--ff-alert-color, var(--accent)));
    flex-shrink: 0;
  }
/* Alert text column — header + body. Tight gap. Mirrors .mw-insight__text. */
.ff-alert__text {
    display: flex;
    flex-direction: column;
    gap: 0.1875rem;
    flex: 1 1 auto;
    min-width: 0;
  }
.ff-alert__header {
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 600;
    color: oklch(var(--foreground));
    line-height: 1.2;
  }
.ff-alert__body {
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 400;
    color: oklch(var(--muted-foreground));
    line-height: 1.35;
  }
/* ─── PPL donut ring well ───────────────────────────────────────────────────
     Mirrors .mw-ring-well / .wq-ring-well: circular recessed area hosting the
     donut SVG. Deeper inset than .neomorph-inset-sm (5px dark + hairline rim)
     = engraved look. Sized to wrap the donut with breathing room. */
.ppl-ring-well {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    background-color: oklch(var(--background));
    box-shadow: var(--ppl-ring-well);
    flex-shrink: 0;
  }
/* ─── PPL arc glow ──────────────────────────────────────────────────────────
     Soft drop-shadow halo on the donut arcs. Reads the per-arc color via
     --ppl-arc-rgb set on each arc element (orange/blauw/groen). Mirrors
     .mw-ring-glow / .wq-arc-glow. */
.ppl-arc-glow {
    filter: drop-shadow(
        0 0 5px rgba(var(--ppl-arc-rgb, var(--accent-rgb)), 0.55)
      )
      drop-shadow(0 0 12px rgba(var(--ppl-arc-rgb, var(--accent-rgb)), 0.22));
  }
/* ─── PPL in-ring percentage labels ─────────────────────────────────────────
     Percentage labels positioned IN the ring (not outside). Each label sits
     along its arc segment, centered. Display font, bold, color matches the arc.
     --ppl-arc-rgb is set per-label to match the parent arc color. */
.ppl-ring-label {
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 700;
    color: rgb(var(--ppl-arc-rgb, var(--accent-rgb)));
    line-height: 1;
    pointer-events: none;
    text-anchor: middle;
    dominant-baseline: middle;
  }
/* ─── PPL per-spiergroep mini-stats ─────────────────────────────────────────
     Compact row per spiergroep: colored dot + name + percentage. Reuses the
     .ppl-arc-rgb per row so the dot color matches the donut segment. */
.ppl-mini-stat {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-radius: 0.5rem;
    background-color: oklch(var(--card));
    box-shadow: var(--neomorph-shadow-sm);
  }
.ppl-mini-stat__dot {
    width: 10px;
    height: 10px;
    border-radius: 9999px;
    background-color: rgb(var(--ppl-arc-rgb, var(--accent-rgb)));
    box-shadow: 0 0 5px rgba(var(--ppl-arc-rgb, var(--accent-rgb)), 0.45);
    flex-shrink: 0;
  }
.ppl-mini-stat__name {
    font-family: var(--font-body);
    font-size: 0.75rem;
    font-weight: 500;
    color: oklch(var(--foreground));
    flex: 1 1 auto;
    min-width: 0;
    line-height: 1.2;
  }
.ppl-mini-stat__pct {
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 700;
    color: rgb(var(--ppl-arc-rgb, var(--accent-rgb)));
    line-height: 1;
    flex-shrink: 0;
  }
/* ─── Overload nav-card ─────────────────────────────────────────────────────
     Neumorphic raised card (rounded-xl) hosting a mini-sparkline preview of the
     current week volume + a trend pijl (↑/↓/→) + delta cijfer vs vorige week.
     Whole card is clickable → navigeert naar volledige Overload Progression
     view. Mirrors .wq-card / .mw-insight structure. */
.ol-nav-card {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 0.875rem;
    border-radius: 0.75rem;
    background-color: oklch(var(--card));
    box-shadow: var(--neomorph-shadow-sm);
    transition: box-shadow 200ms cubic-bezier(0.4, 0, 0.2, 1), transform 200ms
      cubic-bezier(0.4, 0, 0.2, 1);
    cursor: pointer;
    contain: layout style;
  }
.ol-nav-card:active {
    transform: scale(0.99) translateZ(0);
    box-shadow: var(--neomorph-pressed);
  }
/* ─── Overload sparkline preview area ───────────────────────────────────────
     Inset well hosting the mini sparkline SVG so it reads as a sculpted recess,
     not a flat sticker. Mirrors .mw-tile-well depth language (lighter inset). */
.ol-nav-spark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 40px;
    border-radius: 0.5rem;
    background-color: oklch(var(--background));
    box-shadow: var(--ol-nav-spark);
    flex-shrink: 0;
    overflow: hidden;
  }
/* Sparkline SVG stroke — accent color with a soft glow. */
.ol-nav-spark-line {
    stroke: var(--accent-hex);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    fill: none;
    filter: drop-shadow(0 0 3px rgba(var(--accent-rgb), 0.45));
  }
/* ─── Overload text column ───────────────────────────────────────────────────
     Header label + name on one line, trend pijl + delta on the next. Mirrors
     .wq-text / .mw-insight__text structure. */
.ol-nav-text {
    display: flex;
    flex-direction: column;
    gap: 0.1875rem;
    flex: 1 1 auto;
    min-width: 0;
  }
.ol-nav-header {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    line-height: 1.15;
  }
.ol-nav-header__label {
    font-family: var(--font-body);
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: oklch(var(--muted-foreground));
  }
.ol-nav-header__name {
    font-family: var(--font-display);
    font-size: 0.9375rem;
    font-weight: 600;
    color: oklch(var(--foreground));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
/* Trend row — pijl + delta cijfer. Color reflects direction. */
.ol-nav-trend {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-family: var(--font-display);
    font-size: 0.8125rem;
    font-weight: 700;
    line-height: 1.2;
  }
/* ─────────────────────────────────────────────────────────────────────────── */
.op-stat-cell {
    box-shadow: var(--op-stat-cell-well);
  }
.op-radar-well {
    box-shadow: var(--op-radar-well);
  }
.op-hero-metric {
    font-size: var(--op-hero-metric-size);
    font-weight: var(--op-hero-metric-weight);
    line-height: var(--op-hero-metric-line);
    letter-spacing: var(--op-hero-metric-tracking);
    color: oklch(var(--accent));
  }
.op-stat-secondary {
    font-size: var(--op-stat-secondary-size);
    font-weight: var(--op-stat-secondary-weight);
    line-height: var(--op-stat-secondary-line);
    color: var(--foreground);
  }
.op-stat-label {
    font-size: var(--op-stat-label-size);
    font-weight: var(--op-stat-label-weight);
    letter-spacing: var(--op-stat-label-tracking);
    text-transform: uppercase;
    color: var(--muted-foreground);
  }
.op-radar-axis-value {
    font-size: var(--op-radar-axis-value-size);
    font-weight: var(--op-radar-axis-value-weight);
    color: var(--muted-foreground);
  }
.op-coaching {
    box-shadow: var(--op-coaching-ring), var(--op-coaching-glow);
  }
/* VSSheet re-centering — the shadcn SheetContent defaults to side="right"
     (fixed inset-y-0 right-0 h-full w-3/4 sm:max-w-sm), a right-anchored
     drawer. On mobile (375px/430px) the panel spans most of the width but is
     pinned to the right edge with a slide-in-from-right animation, so every
     centered child (avatars, VS badge, period toggle, spider chart, PPL
     donuts) reads as shifted to one side. This override re-anchors the panel
     to the horizontal center: left:0 + right:0 + margin-inline:auto centers
     it within the viewport, max-width caps it on larger screens, and the
     slide-in-from-right animation is replaced with a centered fade so the
     panel no longer appears to enter from the right edge. The inner content
     layout (flex flex-col gap-5 pt-6 pb-10 px-4) is already correctly
     centered — only the outer panel anchoring needed fixing. */
.vs-sheet-content {
    left: 0 !important;
    right: 0 !important;
    margin-inline: auto !important;
    width: 100% !important;
    max-width: 28rem !important;
    /* Safe-area insets so the header (avatars, VS badge, period toggle) clears
       the notch/status bar on modern phones (iPhone, Samsung) and the PPL
       Balance section at the bottom clears the home indicator. The inner
       wrapper's pt-6/pb-10 still provides the visual margin after the inset. */
    padding-top: env(safe-area-inset-top) !important;
    padding-bottom: env(safe-area-inset-bottom) !important;
    /* Neutralize the right-anchored slide-in; use a centered fade + slight
       scale so the panel enters from the middle, not the right edge. */
    animation: vs-sheet-enter 0.2s ease-in-out !important;
  }
/* Reposition the shadcn SheetContent's injected X close button so it sits
     BELOW the notch/status bar on modern phones. The default absolute
     top-2 right-2 (sheet.tsx) ignores the .vs-sheet-content safe-area
     padding (absolute positioning is not affected by padding), so on
     notched devices the X renders behind the notch and is unreachable.
     This override is scoped to .vs-sheet-content only — other sheets in
     the app keep the default top-2 right-2 positioning. The button keeps
     its h-11 w-11 hit target (44px) and right-2 horizontal offset.
     Selector: the injected SheetPrimitive.Close renders as a <button>
     with the absolute top-2 right-2 classes as a direct child of
     SheetContent; we match it via the lucide-x icon it contains. */
.vs-sheet-content > button:has(> svg.lucide-x) {
    top: calc(env(safe-area-inset-top) + 8px) !important;
    right: 0.5rem !important;
  }
@keyframes vs-sheet-enter {
    from {
      opacity: 0;
      transform: scale(0.98);
    }
    to {
      opacity: 1;
      transform: scale(1);
    }
  }
@media (prefers-reduced-motion: reduce) {
    .vs-sheet-content {
      animation: none !important;
    }
  }
/* ════════════════════════════════════════════════════════════════════════
     MACROS — Nutrition dashboard utilities. Engraved-well classes mirror the
     .wq-ring-well / .op-card-well lineage; each macro arc reads its own
     --mn-arc-rgb so all four rings glow in their own color. Works in BOTH
     themes via the --mn-* tokens. Respects prefers-reduced-motion.
     ════════════════════════════════════════════════════════════════════════ */
.mn-card {
    box-shadow: var(--mn-card-well);
  }
.mn-ring-well {
    box-shadow: var(--mn-ring-well);
  }
.mn-meal-well {
    box-shadow: var(--mn-meal-well);
  }
.mn-item-well {
    box-shadow: var(--mn-item-well);
  }
/* Macro arc glow — soft drop-shadow halo on ring arcs. Reads --mn-arc-rgb
     set per arc element (falls back to --accent-rgb). */
/* Macro arc breathing glow — subtle pulse mirroring mw-arc-glow-pulse but
     reading --mn-arc-rgb per arc. */
/* Nutrition day-dot glow — soft warm halo on logged nutrition day-dots. */
/* Nutrition day-dot — 44px tap target, engraved well, accent glow when
     logged (data-logged="true"), quiet engraved empty when not. */
.mn-dot {
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 9999px;
    box-shadow: var(--mn-dot-well);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--muted-foreground);
  }
.mn-dot[data-logged="true"] {
    box-shadow: var(--mn-dot-well), var(--mn-dot-glow);
    color: var(--accent-hex);
  }
.mn-dot[data-today="true"] {
    box-shadow: var(--mn-dot-well), 0 0 0 1.5px rgba(var(--accent-rgb), 0.7);
  }
/* Macro ring in-ring label — display font, color matches the arc via
     --mn-arc-rgb (falls back to accent). */
/* Macro mini-stat row — dot + name + value, dot reads --mn-arc-rgb. */
/* Macro progress bar track — 5px engraved inset hosting the macro fill. */
/* Over-goal macro state — soft red tint on value + bar when intake exceeds
     the goal. */
.mn-over {
    color: rgb(var(--mn-over-rgb));
  }
.mn-bar-fill.mn-over {
    background: rgb(var(--mn-over-rgb));
    box-shadow: 0 0 6px rgba(var(--mn-over-rgb), 0.55);
  }
/* Macro value typography — big Space Grotesk number for calorie hero +
     macro values. */
.mn-value {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--foreground);
  }
/* Macro label typography — tiny uppercase muted label above values. */
.mn-label {
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--muted-foreground);
  }
/* Macro segmented pill — raised neumorphic inactive, accent active.
     Mirrors the .op-pill pattern. */
/* Macro quick-add button — raised neumorphic with accent plus icon. */
/* Macro streak flame glow — soft warm halo on the nutrition streak counter
     (uses --accent-rgb, mirrors --streak-glow). */
.mn-streak-glow {
    box-shadow: var(--streak-glow);
  }
/* Macro insight card — neumorphic card with 3px accent left border,
     mirrors .mw-insight. */
/* Macro segmented control — engraved track hosting raised active pill. */
@keyframes mn-arc-glow-pulse {
    0%,
    100% {
      filter: drop-shadow(
        0 0 4px rgba(var(--mn-arc-rgb, var(--accent-rgb)), 0.4)
      );
    }
    50% {
      filter: drop-shadow(
        0 0 8px rgba(var(--mn-arc-rgb, var(--accent-rgb)), 0.7)
      );
    }
  }
/* ════════════════════════════════════════════════════════════════════════
     FASE 3 — CHALLENGECENTRUM utilities
     Additive .cc-* classes for the Challengecentrum section: three status
     groups (Voorgesteld / Actief / Afgerond), a status filter segmented
     control, a countdown timer chip, and lifecycle action buttons
     (accepteren / afwijzen / afwikkelen / rematch) with disabled states.
     Reuses --ch-* / --lc-* / --accent-rgb / --buddy-rgb lineage. No existing
     tokens modified.
     ════════════════════════════════════════════════════════════════════════ */
/* Status group container — engraved recess hosting a group's challenges.
     Sets --cc-group-rgb so the header dot + glow read the per-group color. */
.cc-group {
    box-shadow: var(--cc-group-well);
    border-radius: 1.25rem;
  }
.cc-group--proposed {
    --cc-group-rgb: var(--cc-proposed-rgb);
  }
.cc-group--active {
    --cc-group-rgb: var(--cc-active-rgb);
  }
.cc-group--done {
    --cc-group-rgb: var(--cc-done-rgb);
  }
/* Group header row — title + count pill on the left, status dot on the
     right. */
.cc-group__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
  }
.cc-group__title {
    font-family: var(--font-display);
    font-weight: 600;
    color: var(--foreground);
  }
.cc-group__count {
    font-family: var(--font-display);
    font-size: 0.75rem;
    font-weight: 600;
    color: rgb(var(--cc-group-rgb, var(--cc-proposed-rgb)));
    background: rgba(var(--cc-group-rgb, var(--cc-proposed-rgb)), 0.14);
    border-radius: 9999px;
    padding: 0.125rem 0.5rem;
  }
/* Status dot — colored indicator with a soft per-group glow. */
.cc-group__dot {
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 9999px;
    background: rgb(var(--cc-group-rgb, var(--cc-proposed-rgb)));
    box-shadow: 0 0 6px rgba(var(--cc-group-rgb, var(--cc-proposed-rgb)), 0.5);
    flex-shrink: 0;
  }
/* Individual challenge card — engraved recess inside a group. */
.cc-card {
    box-shadow: var(--cc-card-well);
    border-radius: 1rem;
  }
/* Empty state for a status group — quiet inset well + short explanation. */
.cc-group__empty {
    box-shadow: var(--cc-countdown-well);
    border-radius: 1rem;
    color: var(--muted-foreground);
  }
/* Status filter — engraved segmented track hosting the filter options. */
.cc-filter {
    box-shadow: var(--cc-filter-well);
    border-radius: 9999px;
  }
.cc-filter__option {
    border-radius: 9999px;
    color: var(--muted-foreground);
    transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1), color 0.2s;
  }
.cc-filter__option--active {
    box-shadow: var(--cc-filter-active-glow);
    color: oklch(var(--accent));
    font-weight: 600;
  }
/* Countdown timer chip — engraved pill showing time to window end. */
.cc-countdown {
    box-shadow: var(--cc-countdown-well);
    border-radius: 9999px;
    font-family: var(--font-display);
    font-weight: 600;
    color: var(--foreground);
  }
/* Urgent countdown — orange glow + accent text when time is running low. */
.cc-countdown--urgent {
    box-shadow: var(--cc-countdown-glow);
    color: oklch(var(--accent));
  }
/* Lifecycle action buttons — raised neumorphic with per-action glow. */
.cc-action {
    border-radius: 0.75rem;
    font-weight: 600;
    transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1), transform 0.2s,
      opacity 0.2s;
  }
.cc-action:active {
    transform: scale(0.98);
  }
/* Accept — orange primary action (voorgesteld → geaccepteerd). */
.cc-action--accept {
    box-shadow: var(--cc-accept-glow);
    color: oklch(var(--accent));
    background: rgba(var(--accent-rgb), 0.14);
  }
/* Decline — muted red destructive action (voorgesteld → afgewezen). */
.cc-action--decline {
    box-shadow: var(--cc-decline-glow);
    color: rgb(var(--cc-decline-rgb));
    background: rgba(var(--cc-decline-rgb), 0.14);
  }
/* Settle — buddy-blue action (actief → afgewikkeld). */
.cc-action--settle {
    box-shadow: var(--cc-settle-glow);
    color: rgb(var(--buddy-rgb));
    background: rgba(var(--buddy-rgb), 0.14);
  }
/* Rematch — accent gradient + breathing glow (afgerond → nieuwe ronde).
     Reuses --ch-rematch-glow for the resting halo and the existing
     blueprint-save-pulse keyframe (breathing boxShadow on --accent-rgb) for
     the animation — no new keyframe needed. */
.cc-action--rematch {
    background: linear-gradient(135deg, var(--accent-hex), var(--accent-dim));
    color: var(--accent-foreground);
    box-shadow: var(--ch-rematch-glow);
    animation: blueprint-save-pulse 3.2s ease-in-out infinite;
  }
/* Disabled state — unavailable lifecycle actions read as inert. */
.cc-action:disabled,
  .cc-action--disabled {
    box-shadow: none;
    color: rgb(var(--cc-disabled-rgb));
    background: rgba(var(--cc-disabled-rgb), 0.12);
    opacity: var(--cc-disabled-opacity);
    cursor: not-allowed;
    transform: none;
    animation: none;
  }
@media (prefers-reduced-motion: reduce) {
    .cc-action--rematch {
      animation: none !important;
    }
  }
/* ════════════════════════════════════════════════════════════════════════
     FASE 5 — GEDEELD PLAN utilities
     Additive .sp-* classes for the shared training plan: a raised neumorphic
     card, an engraved day-row well, a joint-goal cell well, a joint progress
     track + orange fill, per-buddy completion chips (orange = self via
     --accent-rgb, blue = buddy via --buddy-rgb), and a quiet empty state.
     Reuses the --sp-* token lineage. No existing tokens modified.
     ════════════════════════════════════════════════════════════════════════ */
/* Shared plan outer card — raised neumorphic surface hosting the whole
     shared plan. */
/* Shared training day row — engraved recess hosting a single day. */
/* Joint goal cell — engraved inset hosting an editable goal input. */
/* Joint progress track — engraved inset hosting the progress fill. */
/* Joint progress fill — orange glowing fill (uses --accent-rgb). */
/* Per-buddy completion chip — self = orange (--accent-rgb), buddy = blue
     (--buddy-rgb). The --sp-chip-rgb variable is set per chip. */
/* Empty state — quiet inset well + short explanation. */
/* ════════════════════════════════════════════════════════════════════════
     BLUEPRINT SHARING utilities
     Additive .sh-* classes for the blueprint-sharing feature: a public
     read-only shared view (distinct from the owner's edit view), share-link
     generation, and the import action. The PUBLIC view uses buddy-blue
     (--buddy-rgb) as its distinguishing accent; the share/import CTAs use the
     orange accent (--accent-rgb). Reuses the --sh-* token lineage. No existing
     tokens modified.
     ════════════════════════════════════════════════════════════════════════ */
/* Public shared-view outer card — raised neumorphic surface hosting the
     whole public blueprint. */
.sh-card {
    box-shadow: var(--sh-card-well);
    border-radius: 1.25rem;
  }
/* Public shared-view header band — blue-tinted surface (uses --buddy-rgb)
     marking the read-only "shared showcase", visually distinct from the
     owner's editable view. */
.sh-header {
    background: rgba(var(--sh-header-rgb), 0.1);
    box-shadow: var(--sh-header-glow);
    border-radius: 1rem;
  }
/* Public badge chip — engraved pill hosting "Gedeeld plan" / "Alleen-lezen".
     The --sh-chip-rgb variable is set per chip (blue = public/read-only). */
.sh-badge {
    box-shadow: var(--sh-badge-well);
    color: rgb(var(--sh-chip-rgb, var(--buddy-rgb)));
    background: rgba(var(--sh-chip-rgb, var(--buddy-rgb)), 0.12);
    border-radius: 9999px;
  }
/* Read-only training day row — engraved recess hosting a single day. */
.sh-day-row {
    box-shadow: var(--sh-day-well);
    border-radius: 1rem;
  }
/* Exercise spec cell — engraved inset hosting per-exercise specs
     (sets/reps/rust/cardio) in read-only. */
.sh-spec-cell {
    box-shadow: var(--sh-spec-well);
    border-radius: 0.75rem;
  }
/* Public eyebrow chip — engraved pill hosting "Gedeeld door {naam}". */
.sh-eyebrow {
    box-shadow: var(--sh-eyebrow-well);
    border-radius: 9999px;
    color: var(--muted-foreground);
  }
/* Import CTA — orange primary action (logged-in user imports a copy). */
.sh-import-cta {
    background: linear-gradient(135deg, var(--accent-hex), var(--accent-dim));
    color: var(--accent-foreground);
    box-shadow: var(--sh-import-glow);
    animation: blueprint-save-pulse 3.2s ease-in-out infinite;
    border-radius: 0.875rem;
    font-weight: 600;
    transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1), transform 0.2s;
  }
.sh-import-cta:active {
    transform: scale(0.98);
  }
/* Share CTA — orange primary action (owner generates + copies share link). */
.sh-share-cta {
    background: linear-gradient(135deg, var(--accent-hex), var(--accent-dim));
    color: var(--accent-foreground);
    box-shadow: var(--sh-share-glow);
    border-radius: 0.875rem;
    font-weight: 600;
    transition: box-shadow 0.2s cubic-bezier(0.4, 0, 0.2, 1), transform 0.2s;
  }
.sh-share-cta:active {
    transform: scale(0.98);
  }
/* Share-link copy field — engraved inset hosting the read-only share URL. */
.sh-link-field {
    box-shadow: var(--sh-link-well);
    border-radius: 0.75rem;
    color: var(--muted-foreground);
  }
/* Login-prompt banner — engraved recess hosting the "Log in om te
     importeren" hint for non-logged-in visitors. */
.sh-login-banner {
    box-shadow: var(--sh-login-well);
    border-radius: 1rem;
    color: var(--muted-foreground);
  }
@media (prefers-reduced-motion: reduce) {
    .sh-import-cta {
      animation: none !important;
    }
  }
.\[color-scheme\:light\] {
  color-scheme: light;
}

/* font-display: optional — eliminates FOUT/swap layout shift on first
   render. Browsers that already have the font cached use it immediately;
   uncached fonts are fetched with a tiny low-priority window and only
   applied if ready in time, otherwise the fallback stays for the session.
   This trades a one-time "no custom font" render (on very slow first
   loads) for a stable, jump-free layout on every open. */
@font-face {
  font-family: "Space Grotesk";
  src: url("/assets/fonts/SpaceGrotesk.woff2") format("woff2");
  font-display: optional;
}

@font-face {
  font-family: "General Sans";
  src: url("/assets/fonts/GeneralSans.woff2") format("woff2");
  font-display: optional;
}

/* ─────────────────────────────────────────────────────────────────────────── */
/* Start Workout button — slow neon glow pulse (10s per cycle).
   Defined directly in CSS (not via Tailwind theme.extend) to bypass any
   bundling/caching layer that could ship a stale or differently-tuned
   animation. Uses a unique name (repstatSlowGlowPulse / .repstat-slow-glow-pulse)
   that does not match the old start-workout-button-glow name, so a cached
   old stylesheet cannot accidentally reapply the previous fast pulse.

   Rhythm over the 10s cycle (1s = 10%):
     - 0%   → 30%  : 3s ease-in-out rise  (dim  → bright)
     - 30%  → 50%  : 2s rest at bright   (rustpauze na oplichten)
     - 50%  → 80%  : 3s ease-in-out fall  (bright → dim)
     - 80%  → 100% : 2s rest at dim       (rustpauze voor volgende slag)
   The inner neumorphic shadow (8px 8px 16px / -8px -8px 16px / inset) is
   preserved on every phase so the button keeps its tactile depth; only the
   outer orange halo breathes 18px @ 0.45 → 34px @ 0.8. Reads --accent-rgb
   directly (theme-agnostic). Active only in rest state (no active workout) —
   HomePage.tsx toggles the class based on !hasActiveWorkout.
   Reduced-motion users get a static glow via the override in the
   @media (prefers-reduced-motion: reduce) block below. */
@keyframes repstatSlowGlowPulse {
  0%,
  100% {
    box-shadow:
      8px 8px 16px rgba(0, 0, 0, 0.4), -8px -8px 16px rgba(255, 255, 255, 0.05),
      inset 0 1px 0 rgba(255, 255, 255, 0.15),
      0 0 18px rgba(var(--accent-rgb), 0.45);
  }
  30%,
  50% {
    box-shadow:
      8px 8px 16px rgba(0, 0, 0, 0.4), -8px -8px 16px rgba(255, 255, 255, 0.05),
      inset 0 1px 0 rgba(255, 255, 255, 0.15),
      0 0 34px rgba(var(--accent-rgb), 0.8);
  }
  80% {
    box-shadow:
      8px 8px 16px rgba(0, 0, 0, 0.4), -8px -8px 16px rgba(255, 255, 255, 0.05),
      inset 0 1px 0 rgba(255, 255, 255, 0.15),
      0 0 18px rgba(var(--accent-rgb), 0.45);
  }
}

.repstat-slow-glow-pulse {
  animation: repstatSlowGlowPulse 10s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}

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

  .neomorph,
  .neomorph-sm,
  .neomorph-lg,
  .neomorph-xl,
  .neomorph-button,
  .neomorph-hover,
  .template-card-refined,
  .template-action-button {
    transition: none !important;
    transform: none !important;
  }

  /* Start Workout button glow — essential visual signal for the primary
     action. The global rule above would fully kill the animation, leaving
     the button with no orange glow on the light theme. Instead, override
     locally: keep a static orange box-shadow glow (no motion) so
     reduced-motion users still see the call-to-action emphasis. The
     animation class (.repstat-slow-glow-pulse) and its keyframes
     (repstatSlowGlowPulse) are defined at the top level of index.css so
     they bypass Tailwind's theme.extend pipeline entirely. The text itself
     is always static — only the button's box-shadow pulses. */
  .repstat-slow-glow-pulse {
    animation: none !important;
    box-shadow:
      8px 8px 16px rgba(0, 0, 0, 0.4), -8px -8px 16px
      rgba(255, 255, 255, 0.05), inset 0 1px 0 rgba(255, 255, 255, 0.15),
      0 0 26px rgba(var(--accent-rgb), 0.65) !important;
  }
}

/* Mobile-specific optimizations */
@media (max-width: 640px) {
  /* Ensure minimum touch target sizes — iOS/Android HIG 44x44px.
     Includes text/number/email/tel/password inputs and textareas so every
     form control is comfortably tappable on mobile. min-width: 44px only
     applies to tap targets (buttons/links/checkboxes/radios); inputs keep
     their full-width layout and only get the height floor. */
  button,
  a,
  input[type="checkbox"],
  input[type="radio"] {
    min-height: 44px;
    min-width: 44px;
  }

  input[type="text"],
  input[type="number"],
  input[type="email"],
  input[type="tel"],
  input[type="password"],
  input[type="date"],
  input[type="time"],
  input[type="datetime-local"],
  textarea,
  select {
    min-height: 44px;
  }

  /* Optimize spacing for mobile */
  .mobile-compact {
    padding: 0.75rem;
  }

  /* Better readability on small screens */
  body {
    font-size: 16px;
    line-height: 1.5;
  }
}

/* High contrast mode support */
@media (prefers-contrast: high) {
  :root {
    --foreground: 0.08 0 0;
    --muted-foreground: 0.38 0 0;
  }

  .dark {
    --foreground: 0.99 0 0;
    --muted-foreground: 0.82 0 0;
  }

  /* Enhance borders in high contrast mode */
  .neomorph,
  .neomorph-sm,
  .neomorph-lg,
  .neomorph-xl,
  .template-card-refined,
  .template-action-button {
    border: 1px solid oklch(var(--border));
  }
}

/* Modal search input — placeholder + caret colors so it works in both themes regardless of
   overlay context. Background is intentionally NOT set here so the .bp2-search-input wrapper's
   single subtle inset neumorph is the only background layer (inner Input stays transparent). */
/* Keep the caret fully inside the compact h-7 box: force zero vertical padding and a
   tight line-height so the shadcn base py-1 / default line-height can never push the
   caret above the top edge, regardless of Tailwind class application order. */
.modal-exercise-search,
input.modal-exercise-search {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
  line-height: 1 !important;
  /* Keep the font at 16px (>= the iOS auto-zoom threshold) so focusing the
     input does NOT zoom the page on iOS. The caret stays fully inside the
     compact h-7 box because line-height:1 + zero vertical padding keep the
     line box tight; the 16px font fits within the 28px box. */
  font-size: 16px !important;
}
:root:not(.dark) .modal-exercise-search,
:root:not(.dark) input.modal-exercise-search {
  color: #1a1a1a !important;
  caret-color: #1a1a1a !important;
  /* Transparent border so only the .bp2-search-input wrapper ring shows —
     avoids a layered ring step on the right edge of the inner rounded-lg. */
  border: none !important;
  border-color: transparent !important;
}
:root:not(.dark) .modal-exercise-search::-moz-placeholder {
  color: #6b6b6b !important;
  opacity: 1 !important;
}
:root:not(.dark) .modal-exercise-search::placeholder {
  color: #6b6b6b !important;
  opacity: 1 !important;
}

.dark .modal-exercise-search,
.dark input.modal-exercise-search {
  color: #f0f0f0 !important;
  caret-color: #f0f0f0 !important;
  /* Transparent border so only the .bp2-search-input wrapper ring shows —
     avoids a layered ring step on the right edge of the inner rounded-lg. */
  border: none !important;
  border-color: transparent !important;
}
.dark .modal-exercise-search::-moz-placeholder {
  color: #888888 !important;
  opacity: 1 !important;
}
.dark .modal-exercise-search::placeholder {
  color: #888888 !important;
  opacity: 1 !important;
}

/* ===== Overload Progression detail page utility classes ===== */
.op-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 1rem;
  border-radius: 9999px;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--muted);
  background: var(--card);
  box-shadow: var(--op-pill-raised);
  transition: box-shadow 0.2s ease, color 0.2s ease, background 0.2s ease;
  cursor: pointer;
  border: none;
}
.op-pill:hover {
  color: var(--accent);
}
.op-pill--active {
  color: #fff;
  background: var(--accent);
  box-shadow: var(--op-pill-active-glow);
}
.op-pill--active:hover {
  color: #fff;
}
.op-hero {
  position: relative;
  padding: 1.5rem;
  border-radius: 1rem;
  background: var(--card);
  box-shadow: var(--op-hero-well);
}
.op-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1.5rem 1rem;
  border-radius: 1rem;
  background: var(--card);
  box-shadow: var(--op-empty-well);
  text-align: center;
}
.op-avg-line {
  stroke: oklch(var(--accent-rgb) / 0.55);
  stroke-width: 1.5;
  stroke-dasharray: 5 4;
  fill: none;
}
.op-star-glow {
  filter: drop-shadow(0 0 4px oklch(var(--accent-rgb) / 0.65));
}

/* Fase 1 — Buddy Tab Challenges. LIVE pill breathing animation: opacity
   0.6↔1 + scale 0.97↔1, 2s ease-in-out infinite. Respects the global
   prefers-reduced-motion guard at index.css line 4340 plus the local block
   below. */
@keyframes wvc-live-pulse {
  0%,
  100% {
    opacity: 0.6;
    transform: scale(0.97);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}
.neomorph-wvc-card {
  box-shadow: var(--wvc-card-well);
}
.neomorph-wvc-sub {
  box-shadow: var(--wvc-sub-well);
}
.neomorph-lb-seg {
  box-shadow: var(--lb-seg-well);
}
.neomorph-lb-row {
  box-shadow: var(--lb-row-well);
}
.neomorph-lb-avg {
  box-shadow: var(--lb-avg-well);
}
.neomorph-pr-card {
  background: var(--card);
  box-shadow: var(--pr-card-well);
  border-radius: 1rem;
}
.neomorph-pr-seg {
  background: var(--card);
  box-shadow: var(--pr-seg-well);
  border-radius: 9999px;
}
.neomorph-pr-row {
  background: var(--card);
  box-shadow: var(--pr-row-well);
  border-radius: 0.75rem;
}
.neomorph-streak-card {
  background: var(--card);
  box-shadow: var(--streak-card-well);
  border-radius: 1rem;
}
.neomorph-streak-ring {
  box-shadow: var(--streak-ring-well);
}
.neomorph-mbr-card {
  background: var(--card);
  box-shadow: var(--mbr-card-well);
  border-radius: 1rem;
}
.neomorph-mbr-bar {
  box-shadow: var(--mbr-bar-well);
}
.neomorph-mbr-seg {
  background: var(--card);
  box-shadow: var(--mbr-seg-well);
  border-radius: 9999px;
}
.neomorph-mbr-sub {
  box-shadow: var(--mbr-sub-well);
}
@media (prefers-reduced-motion: reduce) {
  .wvc-live-pulse {
    animation: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   SETTINGS PAGE NEUMORPHIC REFINEMENT
   Additive component classes for the SettingsPage upgrade. Reuse existing
   tokens only — --accent, --accent-hex, --accent-rgb, --accent-foreground,
   --destructive, --foreground, --muted-foreground, --neomorph-shadow-sm,
   --neomorph-inset, --neomorph-inset-sm, --neomorph-hover, --neomorph-pressed,
   --neomorph-accent-ring, --font-display, --font-body. No existing tokens,
   accent presets, or theme variables are modified. All classes work in both
   :root (light) and .dark themes via inherited variables. 44px tap targets
   enforced where the element is a primary interactive control.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ─── Keyboard focus ring ─────────────────────────────────────────────────
   Accent-colored outline for keyboard navigation. Uses var(--accent) so it
   follows the active accent preset (Ember/Volt/Venom/Coral). Apply on any
   focusable element via class or compose with &:focus-visible. */
.neomorph-focus-ring:focus-visible {
  outline: 2px solid oklch(var(--accent));
  outline-offset: 2px;
  border-radius: inherit;
}

/* ─── Settings section header ──────────────────────────────────────────────
   Flex row: icon + title. Space Grotesk semibold title (1.25rem), 1.5rem icon,
   margin-bottom for breathing room. Works in both themes via --foreground. */
.settings-section-header {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-bottom: 0.875rem;
}

.settings-section-header__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
  color: oklch(var(--accent));
}

.settings-section-header__title {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: oklch(var(--foreground));
}

/* ─── Large toggle switch ──────────────────────────────────────────────────
   Larger track (52×30px) with a 24px thumb that slides right and turns accent
   when checked. Wrapper enforces a 44px tap target via padding. Driven by
   aria-checked on the track or a sibling checkbox + label pattern. */
.neomorph-toggle-lg {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 52px;
  min-width: 52px;
  height: 30px;
  min-height: 30px;
  border-radius: 9999px;
  background-color: oklch(var(--muted));
  box-shadow: var(--neomorph-inset-sm);
  transition: background-color 200ms cubic-bezier(0.4, 0, 0.2, 1), box-shadow
    200ms cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
  flex-shrink: 0;
}

.neomorph-toggle-lg__thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  border-radius: 9999px;
  background-color: oklch(var(--card));
  box-shadow: var(--neomorph-shadow-sm);
  transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1), background-color
    200ms cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
}

.neomorph-toggle-lg[aria-checked="true"],
.neomorph-toggle-lg.is-checked {
  background-color: oklch(var(--accent));
  box-shadow: var(--neomorph-inset-sm), 0 0 0 1px rgba(var(--accent-rgb), 0.45);
}

.neomorph-toggle-lg[aria-checked="true"] .neomorph-toggle-lg__thumb,
.neomorph-toggle-lg.is-checked .neomorph-toggle-lg__thumb {
  transform: translateX(22px);
  background-color: oklch(var(--accent-foreground));
}

/* Wrapper that guarantees the 44px tap target around the toggle. */
.neomorph-toggle-lg__wrap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 7px 4px;
  cursor: pointer;
}

/* ─── Danger button (raised neumorphic, red accent) ─────────────────────────
   Raised look via --neomorph-shadow-sm, 1px destructive border, destructive
   text. Hover/active swap to neumorph-hover / neomorph-pressed. NOT flat. */
.neomorph-button-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.625rem 1.25rem;
  min-height: 44px;
  border-radius: var(--radius);
  background-color: oklch(var(--card));
  border: 1px solid oklch(var(--destructive));
  color: oklch(var(--destructive));
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.875rem;
  box-shadow: var(--neomorph-shadow-sm);
  transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
    cubic-bezier(0.4, 0, 0.2, 1), opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
  will-change: transform;
  contain: layout style;
}

.neomorph-button-danger:hover:not(:disabled) {
  box-shadow: var(--neomorph-hover);
  transform: scale(1.02) translateZ(0);
}

.neomorph-button-danger:active:not(:disabled) {
  box-shadow: var(--neomorph-pressed);
  transform: scale(0.98) translateZ(0);
}

.neomorph-button-danger:focus-visible {
  outline: 2px solid oklch(var(--destructive));
  outline-offset: 2px;
  border-radius: inherit;
}

.neomorph-button-danger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ─── Training day toggle button ───────────────────────────────────────────
   44×44 tap target. Neumorphic-inset when unselected; accent fill + accent-
   foreground text when aria-pressed="true". Rounded. */
.neomorph-day-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 100%;
  min-height: 44px;
  padding: 0.5rem 0.625rem;
  border-radius: var(--radius);
  background-color: oklch(var(--card));
  border: none;
  color: oklch(var(--foreground));
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.875rem;
  box-shadow: var(--neomorph-inset-sm);
  transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), background-color
    150ms cubic-bezier(0.4, 0, 0.2, 1), color 150ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

.neomorph-day-btn:hover:not(:disabled) {
  color: oklch(var(--accent));
}

.neomorph-day-btn:active:not(:disabled) {
  transform: scale(0.97) translateZ(0);
  box-shadow: var(--neomorph-pressed);
}

.neomorph-day-btn[aria-pressed="true"],
.neomorph-day-btn.is-pressed {
  background-color: oklch(var(--accent));
  color: oklch(var(--accent-foreground));
  box-shadow: var(--neomorph-shadow-sm), 0 0 0 1px rgba(var(--accent-rgb), 0.4);
}

.neomorph-day-btn[aria-pressed="true"]:active:not(:disabled),
.neomorph-day-btn.is-pressed:active:not(:disabled) {
  box-shadow: var(--neomorph-pressed);
}

.neomorph-day-btn:focus-visible {
  outline: 2px solid oklch(var(--accent));
  outline-offset: 2px;
  border-radius: inherit;
}

.neomorph-day-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ─── Rest timer preset pill ───────────────────────────────────────────────
   44px tap target, neumorphic-inset unselected, accent fill when selected.
   Rounded pill shape (full radius). */
.neomorph-preset-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.5rem 1.25rem;
  border-radius: 9999px;
  background-color: oklch(var(--card));
  border: none;
  color: oklch(var(--foreground));
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.875rem;
  box-shadow: var(--neomorph-inset-sm);
  transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), background-color
    150ms cubic-bezier(0.4, 0, 0.2, 1), color 150ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 150ms cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

.neomorph-preset-pill:hover:not(:disabled) {
  color: oklch(var(--accent));
}

.neomorph-preset-pill:active:not(:disabled) {
  transform: scale(0.97) translateZ(0);
  box-shadow: var(--neomorph-pressed);
}

.neomorph-preset-pill[aria-pressed="true"],
.neomorph-preset-pill.is-pressed {
  background-color: oklch(var(--accent));
  color: oklch(var(--accent-foreground));
  box-shadow: var(--neomorph-shadow-sm), 0 0 0 1px rgba(var(--accent-rgb), 0.4);
}

.neomorph-preset-pill:focus-visible {
  outline: 2px solid oklch(var(--accent));
  outline-offset: 2px;
  border-radius: inherit;
}

.neomorph-preset-pill:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ─── Accent color swatch ───────────────────────────────────────────────────
   44×44 tap target, neumorphic-inset base, accent ring when aria-checked. */
.neomorph-swatch {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  width: 44px;
  height: 44px;
  border-radius: 9999px;
  background-color: oklch(var(--card));
  border: none;
  box-shadow: var(--neomorph-inset-sm);
  transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms
    cubic-bezier(0.4, 0, 0.2, 1);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  padding: 0;
}

.neomorph-swatch__dot {
  width: 28px;
  height: 28px;
  border-radius: 9999px;
  background-color: var(--swatch-color, oklch(var(--accent)));
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
  flex-shrink: 0;
}

.neomorph-swatch:hover:not(:disabled) {
  transform: scale(1.04) translateZ(0);
}

.neomorph-swatch:active:not(:disabled) {
  transform: scale(0.96) translateZ(0);
  box-shadow: var(--neomorph-pressed);
}

.neomorph-swatch[aria-checked="true"],
.neomorph-swatch.is-checked {
  box-shadow: var(--neomorph-inset-sm), 0 0 0 2px oklch(var(--accent)), 0 0 0
    4px rgba(var(--accent-rgb), 0.25);
}

.neomorph-swatch:focus-visible {
  outline: 2px solid oklch(var(--accent));
  outline-offset: 2px;
  border-radius: inherit;
}

.neomorph-swatch:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.selection\:bg-primary *::-moz-selection {
  background-color: oklch(var(--primary));
}

.selection\:bg-primary *::selection {
  background-color: oklch(var(--primary));
}

.selection\:text-primary-foreground *::-moz-selection {
  color: oklch(var(--primary-foreground));
}

.selection\:text-primary-foreground *::selection {
  color: oklch(var(--primary-foreground));
}

.selection\:bg-primary::-moz-selection {
  background-color: oklch(var(--primary));
}

.selection\:bg-primary::selection {
  background-color: oklch(var(--primary));
}

.selection\:text-primary-foreground::-moz-selection {
  color: oklch(var(--primary-foreground));
}

.selection\:text-primary-foreground::selection {
  color: oklch(var(--primary-foreground));
}

.file\:inline-flex::file-selector-button {
  display: inline-flex;
}

.file\:h-7::file-selector-button {
  height: 1.75rem;
}

.file\:border-0::file-selector-button {
  border-width: 0px;
}

.file\:bg-transparent::file-selector-button {
  background-color: transparent;
}

.file\:text-sm::file-selector-button {
  font-size: 0.875rem;
  line-height: 1.25rem;
}

.file\:font-medium::file-selector-button {
  font-weight: 500;
}

.file\:text-foreground::file-selector-button {
  color: oklch(var(--foreground));
}

.placeholder\:text-muted-foreground::-moz-placeholder {
  color: oklch(var(--muted-foreground));
}

.placeholder\:text-muted-foreground::placeholder {
  color: oklch(var(--muted-foreground));
}

.last\:mb-0:last-child {
  margin-bottom: 0px;
}

.hover\:translate-y-\[-1px\]:hover {
  --tw-translate-y: -1px;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.hover\:scale-105:hover {
  --tw-scale-x: 1.05;
  --tw-scale-y: 1.05;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.hover\:scale-110:hover {
  --tw-scale-x: 1.1;
  --tw-scale-y: 1.1;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.hover\:scale-\[1\.01\]:hover {
  --tw-scale-x: 1.01;
  --tw-scale-y: 1.01;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.hover\:scale-\[1\.02\]:hover {
  --tw-scale-x: 1.02;
  --tw-scale-y: 1.02;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.hover\:bg-\[rgba\(var\(--accent-rgb\)\2c 0\.85\)\]:hover {
  background-color: rgba(var(--accent-rgb),0.85);
}

.hover\:bg-accent:hover {
  background-color: oklch(var(--accent));
}

.hover\:bg-destructive:hover {
  background-color: oklch(var(--destructive));
}

.hover\:bg-muted:hover {
  background-color: oklch(var(--muted));
}

.hover\:text-\[var\(--accent-hex\)\]:hover {
  color: var(--accent-hex);
}

.hover\:text-accent:hover {
  color: oklch(var(--accent));
}

.hover\:text-accent-foreground:hover {
  color: oklch(var(--accent-foreground));
}

.hover\:text-destructive:hover {
  color: oklch(var(--destructive));
}

.hover\:text-destructive-foreground:hover {
  color: oklch(var(--destructive-foreground));
}

.hover\:text-foreground:hover {
  color: oklch(var(--foreground));
}

.hover\:text-muted-foreground:hover {
  color: oklch(var(--muted-foreground));
}

.hover\:text-red-400:hover {
  --tw-text-opacity: 1;
  color: rgb(248 113 113 / var(--tw-text-opacity, 1));
}

.hover\:underline:hover {
  text-decoration-line: underline;
}

.hover\:opacity-100:hover {
  opacity: 1;
}

.hover\:opacity-80:hover {
  opacity: 0.8;
}

.hover\:opacity-90:hover {
  opacity: 0.9;
}

.focus\:bg-accent:focus {
  background-color: oklch(var(--accent));
}

.focus\:text-accent-foreground:focus {
  color: oklch(var(--accent-foreground));
}

.focus\:text-destructive:focus {
  color: oklch(var(--destructive));
}

.focus\:outline-none:focus {
  outline: 2px solid transparent;
  outline-offset: 2px;
}

.focus\:ring-0:focus {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}

.focus\:ring-2:focus {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}

.focus\:ring-ring:focus {
  --tw-ring-color: oklch(var(--ring));
}

.focus\:ring-offset-2:focus {
  --tw-ring-offset-width: 2px;
}

.focus-visible\:border-ring:focus-visible {
  border-color: oklch(var(--ring));
}

.focus-visible\:outline-none:focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
}

.focus-visible\:outline-1:focus-visible {
  outline-width: 1px;
}

.focus-visible\:ring-0:focus-visible {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}

.focus-visible\:ring-2:focus-visible {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}

.focus-visible\:ring-\[3px\]:focus-visible {
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}

.focus-visible\:ring-\[oklch\(var\(--accent\)\)\]:focus-visible {
  --tw-ring-color: oklch(var(--accent));
}

.focus-visible\:ring-\[var\(--accent-rgb\)\]:focus-visible {
  --tw-ring-color: var(--accent-rgb);
}

.focus-visible\:ring-accent:focus-visible {
  --tw-ring-color: oklch(var(--accent));
}

.focus-visible\:ring-transparent:focus-visible {
  --tw-ring-color: transparent;
}

.focus-visible\:ring-offset-2:focus-visible {
  --tw-ring-offset-width: 2px;
}

.focus-visible\:ring-offset-background:focus-visible {
  --tw-ring-offset-color: oklch(var(--background));
}

.active\:scale-95:active {
  --tw-scale-x: .95;
  --tw-scale-y: .95;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.active\:scale-\[0\.98\]:active {
  --tw-scale-x: 0.98;
  --tw-scale-y: 0.98;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.active\:scale-\[0\.99\]:active {
  --tw-scale-x: 0.99;
  --tw-scale-y: 0.99;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.enabled\:hover\:text-\[var\(--accent-hex\)\]:hover:enabled {
  color: var(--accent-hex);
}

.disabled\:pointer-events-none:disabled {
  pointer-events: none;
}

.disabled\:cursor-not-allowed:disabled {
  cursor: not-allowed;
}

.disabled\:opacity-40:disabled {
  opacity: 0.4;
}

.disabled\:opacity-50:disabled {
  opacity: 0.5;
}

.disabled\:opacity-60:disabled {
  opacity: 0.6;
}

.disabled\:hover\:scale-100:hover:disabled {
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.disabled\:active\:scale-100:active:disabled {
  --tw-scale-x: 1;
  --tw-scale-y: 1;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.group:hover .group-hover\:text-accent {
  color: oklch(var(--accent));
}

.group:hover .group-hover\:opacity-100 {
  opacity: 1;
}

.peer:disabled ~ .peer-disabled\:cursor-not-allowed {
  cursor: not-allowed;
}

.peer:disabled ~ .peer-disabled\:opacity-50 {
  opacity: 0.5;
}

.has-\[\>svg\]\:grid-cols-\[calc\(var\(--spacing\)\*4\)_1fr\]:has(>svg) {
  grid-template-columns: calc(var(--spacing) * 4) 1fr;
}

.has-\[\>svg\]\:gap-x-3:has(>svg) {
  -moz-column-gap: 0.75rem;
       column-gap: 0.75rem;
}

.has-\[\>svg\]\:px-2\.5:has(>svg) {
  padding-left: 0.625rem;
  padding-right: 0.625rem;
}

.has-\[\>svg\]\:px-3:has(>svg) {
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}

.has-\[\>svg\]\:px-4:has(>svg) {
  padding-left: 1rem;
  padding-right: 1rem;
}

.data-\[disabled\]\:pointer-events-none[data-disabled] {
  pointer-events: none;
}

.data-\[vaul-drawer-direction\=bottom\]\:inset-x-0[data-vaul-drawer-direction="bottom"] {
  left: 0px;
  right: 0px;
}

.data-\[vaul-drawer-direction\=left\]\:inset-y-0[data-vaul-drawer-direction="left"] {
  top: 0px;
  bottom: 0px;
}

.data-\[vaul-drawer-direction\=right\]\:inset-y-0[data-vaul-drawer-direction="right"] {
  top: 0px;
  bottom: 0px;
}

.data-\[vaul-drawer-direction\=top\]\:inset-x-0[data-vaul-drawer-direction="top"] {
  left: 0px;
  right: 0px;
}

.data-\[vaul-drawer-direction\=bottom\]\:bottom-0[data-vaul-drawer-direction="bottom"] {
  bottom: 0px;
}

.data-\[vaul-drawer-direction\=left\]\:left-0[data-vaul-drawer-direction="left"] {
  left: 0px;
}

.data-\[vaul-drawer-direction\=right\]\:right-0[data-vaul-drawer-direction="right"] {
  right: 0px;
}

.data-\[vaul-drawer-direction\=top\]\:top-0[data-vaul-drawer-direction="top"] {
  top: 0px;
}

.data-\[vaul-drawer-direction\=bottom\]\:mt-24[data-vaul-drawer-direction="bottom"] {
  margin-top: 6rem;
}

.data-\[vaul-drawer-direction\=top\]\:mb-24[data-vaul-drawer-direction="top"] {
  margin-bottom: 6rem;
}

.data-\[orientation\=horizontal\]\:h-px[data-orientation="horizontal"] {
  height: 1px;
}

.data-\[orientation\=vertical\]\:h-full[data-orientation="vertical"] {
  height: 100%;
}

.data-\[size\=default\]\:h-9[data-size="default"] {
  height: 2.25rem;
}

.data-\[size\=sm\]\:h-8[data-size="sm"] {
  height: 2rem;
}

.data-\[vaul-drawer-direction\=bottom\]\:max-h-\[80vh\][data-vaul-drawer-direction="bottom"] {
  max-height: 80vh;
}

.data-\[vaul-drawer-direction\=top\]\:max-h-\[80vh\][data-vaul-drawer-direction="top"] {
  max-height: 80vh;
}

.data-\[orientation\=horizontal\]\:w-full[data-orientation="horizontal"] {
  width: 100%;
}

.data-\[orientation\=vertical\]\:w-px[data-orientation="vertical"] {
  width: 1px;
}

.data-\[vaul-drawer-direction\=left\]\:w-3\/4[data-vaul-drawer-direction="left"] {
  width: 75%;
}

.data-\[vaul-drawer-direction\=right\]\:w-3\/4[data-vaul-drawer-direction="right"] {
  width: 75%;
}

.data-\[side\=bottom\]\:translate-y-1[data-side="bottom"] {
  --tw-translate-y: 0.25rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.data-\[side\=left\]\:-translate-x-1[data-side="left"] {
  --tw-translate-x: -0.25rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.data-\[side\=right\]\:translate-x-1[data-side="right"] {
  --tw-translate-x: 0.25rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.data-\[side\=top\]\:-translate-y-1[data-side="top"] {
  --tw-translate-y: -0.25rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.data-\[state\=checked\]\:translate-x-\[calc\(100\%-2px\)\][data-state="checked"] {
  --tw-translate-x: calc(100% - 2px);
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.data-\[state\=unchecked\]\:translate-x-0[data-state="unchecked"] {
  --tw-translate-x: 0px;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.data-\[state\=closed\]\:animate-none[data-state="closed"] {
  animation: none;
}

.data-\[state\=open\]\:animate-none[data-state="open"] {
  animation: none;
}

.data-\[vaul-drawer-direction\=bottom\]\:rounded-t-lg[data-vaul-drawer-direction="bottom"] {
  border-top-left-radius: var(--radius);
  border-top-right-radius: var(--radius);
}

.data-\[vaul-drawer-direction\=top\]\:rounded-b-lg[data-vaul-drawer-direction="top"] {
  border-bottom-right-radius: var(--radius);
  border-bottom-left-radius: var(--radius);
}

.data-\[vaul-drawer-direction\=bottom\]\:border-t[data-vaul-drawer-direction="bottom"] {
  border-top-width: 1px;
}

.data-\[vaul-drawer-direction\=left\]\:border-r[data-vaul-drawer-direction="left"] {
  border-right-width: 1px;
}

.data-\[vaul-drawer-direction\=right\]\:border-l[data-vaul-drawer-direction="right"] {
  border-left-width: 1px;
}

.data-\[vaul-drawer-direction\=top\]\:border-b[data-vaul-drawer-direction="top"] {
  border-bottom-width: 1px;
}

.data-\[state\=checked\]\:bg-accent[data-state="checked"] {
  background-color: oklch(var(--accent));
}

.data-\[state\=checked\]\:bg-primary[data-state="checked"] {
  background-color: oklch(var(--primary));
}

.data-\[state\=on\]\:bg-accent[data-state="on"] {
  background-color: oklch(var(--accent));
}

.data-\[state\=open\]\:bg-accent[data-state="open"] {
  background-color: oklch(var(--accent));
}

.data-\[state\=open\]\:bg-secondary[data-state="open"] {
  background-color: oklch(var(--secondary));
}

.data-\[state\=unchecked\]\:bg-input[data-state="unchecked"] {
  background-color: oklch(var(--input));
}

.data-\[inset\]\:pl-8[data-inset] {
  padding-left: 2rem;
}

.data-\[placeholder\]\:text-muted-foreground[data-placeholder] {
  color: oklch(var(--muted-foreground));
}

.data-\[state\=on\]\:text-accent-foreground[data-state="on"] {
  color: oklch(var(--accent-foreground));
}

.data-\[state\=open\]\:text-accent-foreground[data-state="open"] {
  color: oklch(var(--accent-foreground));
}

.data-\[variant\=destructive\]\:text-destructive[data-variant="destructive"] {
  color: oklch(var(--destructive));
}

.data-\[disabled\]\:opacity-50[data-disabled] {
  opacity: 0.5;
}

.data-\[state\=closed\]\:duration-200[data-state="closed"] {
  transition-duration: 200ms;
}

.data-\[state\=open\]\:duration-200[data-state="open"] {
  transition-duration: 200ms;
}

.data-\[state\=open\]\:animate-in[data-state="open"] {
  animation-name: enter;
  animation-duration: 150ms;
  --tw-enter-opacity: initial;
  --tw-enter-scale: initial;
  --tw-enter-rotate: initial;
  --tw-enter-translate-x: initial;
  --tw-enter-translate-y: initial;
}

.data-\[state\=closed\]\:animate-out[data-state="closed"] {
  animation-name: exit;
  animation-duration: 150ms;
  --tw-exit-opacity: initial;
  --tw-exit-scale: initial;
  --tw-exit-rotate: initial;
  --tw-exit-translate-x: initial;
  --tw-exit-translate-y: initial;
}

.data-\[state\=closed\]\:fade-out-0[data-state="closed"] {
  --tw-exit-opacity: 0;
}

.data-\[state\=open\]\:fade-in-0[data-state="open"] {
  --tw-enter-opacity: 0;
}

.data-\[state\=closed\]\:zoom-out-95[data-state="closed"] {
  --tw-exit-scale: .95;
}

.data-\[state\=open\]\:zoom-in-95[data-state="open"] {
  --tw-enter-scale: .95;
}

.data-\[state\=closed\]\:duration-200[data-state="closed"] {
  animation-duration: 200ms;
}

.data-\[state\=open\]\:duration-200[data-state="open"] {
  animation-duration: 200ms;
}

.data-\[state\=open\]\:zoom-in-95[data-state="open"] {
    animation: zoom-in-95 400ms cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform, opacity;
  }

.\*\:data-\[slot\=select-value\]\:line-clamp-1[data-slot="select-value"] > * {
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
}

.\*\:data-\[slot\=select-value\]\:flex[data-slot="select-value"] > * {
  display: flex;
}

.\*\:data-\[slot\=select-value\]\:items-center[data-slot="select-value"] > * {
  align-items: center;
}

.\*\:data-\[slot\=select-value\]\:gap-2[data-slot="select-value"] > * {
  gap: 0.5rem;
}

.data-\[variant\=destructive\]\:focus\:text-destructive:focus[data-variant="destructive"] {
  color: oklch(var(--destructive));
}

.group[data-disabled="true"] .group-data-\[disabled\=true\]\:pointer-events-none {
  pointer-events: none;
}

.group\/drawer-content[data-vaul-drawer-direction="bottom"] .group-data-\[vaul-drawer-direction\=bottom\]\/drawer-content\:block {
  display: block;
}

.group\/drawer-content[data-vaul-drawer-direction="bottom"] .group-data-\[vaul-drawer-direction\=bottom\]\/drawer-content\:text-center {
  text-align: center;
}

.group\/drawer-content[data-vaul-drawer-direction="top"] .group-data-\[vaul-drawer-direction\=top\]\/drawer-content\:text-center {
  text-align: center;
}

.group[data-disabled="true"] .group-data-\[disabled\=true\]\:opacity-50 {
  opacity: 0.5;
}

@supports (backdrop-filter:blur(4px)) {

  .supports-\[backdrop-filter\:blur\(4px\)\]\:bg-black\/50 {
    background-color: rgb(0 0 0 / 0.5);
  }

  .supports-\[backdrop-filter\:blur\(4px\)\]\:backdrop-blur-sm {
    --tw-backdrop-blur: blur(4px);
    backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
  }
}

.dark\:border-input:is(.dark *) {
  border-color: oklch(var(--input));
}

.dark\:bg-\[oklch\(0\.45_0\.08_40\/0\.12\)\]:is(.dark *) {
  background-color: oklch(0.45 0.08 40/0.12);
}

.dark\:\[color-scheme\:dark\]:is(.dark *) {
  color-scheme: dark;
}

.dark\:data-\[state\=checked\]\:bg-primary-foreground[data-state="checked"]:is(.dark *) {
  background-color: oklch(var(--primary-foreground));
}

.dark\:data-\[state\=unchecked\]\:bg-foreground[data-state="unchecked"]:is(.dark *) {
  background-color: oklch(var(--foreground));
}

@media (min-width: 360px) {

  .min-\[360px\]\:grid-cols-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 640px) {

  .sm\:mr-auto {
    margin-right: auto;
  }

  .sm\:w-\[90\%\] {
    width: 90%;
  }

  .sm\:max-w-2xl {
    max-width: 42rem;
  }

  .sm\:max-w-lg {
    max-width: 32rem;
  }

  .sm\:max-w-md {
    max-width: 28rem;
  }

  .sm\:max-w-sm {
    max-width: 24rem;
  }

  .sm\:grid-cols-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sm\:grid-cols-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .sm\:grid-cols-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .sm\:grid-cols-7 {
    grid-template-columns: repeat(7, minmax(0, 1fr));
  }

  .sm\:flex-row {
    flex-direction: row;
  }

  .sm\:flex-col {
    flex-direction: column;
  }

  .sm\:items-center {
    align-items: center;
  }

  .sm\:justify-end {
    justify-content: flex-end;
  }

  .sm\:justify-between {
    justify-content: space-between;
  }

  .sm\:gap-2 {
    gap: 0.5rem;
  }

  .sm\:rounded-2xl {
    border-radius: 1rem;
  }

  .sm\:p-4 {
    padding: 1rem;
  }

  .sm\:p-5 {
    padding: 1.25rem;
  }

  .sm\:p-6 {
    padding: 1.5rem;
  }

  .sm\:text-left {
    text-align: left;
  }

  .sm\:text-5xl {
    font-size: 3rem;
    line-height: 1;
  }

  .data-\[vaul-drawer-direction\=left\]\:sm\:max-w-sm[data-vaul-drawer-direction="left"] {
    max-width: 24rem;
  }

  .data-\[vaul-drawer-direction\=right\]\:sm\:max-w-sm[data-vaul-drawer-direction="right"] {
    max-width: 24rem;
  }
}

@media (min-width: 768px) {

  .md\:-mx-4 {
    margin-left: -1rem;
    margin-right: -1rem;
  }

  .md\:mb-2 {
    margin-bottom: 0.5rem;
  }

  .md\:mb-3 {
    margin-bottom: 0.75rem;
  }

  .md\:mt-3 {
    margin-top: 0.75rem;
  }

  .md\:h-5 {
    height: 1.25rem;
  }

  .md\:w-5 {
    width: 1.25rem;
  }

  .md\:grid-cols-2 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .md\:grid-cols-3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .md\:grid-cols-4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .md\:gap-1\.5 {
    gap: 0.375rem;
  }

  .md\:gap-2 {
    gap: 0.5rem;
  }

  .md\:gap-3 {
    gap: 0.75rem;
  }

  .md\:gap-4 {
    gap: 1rem;
  }

  .md\:space-y-2 > :not([hidden]) ~ :not([hidden]) {
    --tw-space-y-reverse: 0;
    margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
    margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
  }

  .md\:space-y-4 > :not([hidden]) ~ :not([hidden]) {
    --tw-space-y-reverse: 0;
    margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
    margin-bottom: calc(1rem * var(--tw-space-y-reverse));
  }

  .md\:space-y-6 > :not([hidden]) ~ :not([hidden]) {
    --tw-space-y-reverse: 0;
    margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
    margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
  }

  .md\:rounded-lg {
    border-radius: var(--radius);
  }

  .md\:p-2 {
    padding: 0.5rem;
  }

  .md\:p-4 {
    padding: 1rem;
  }

  .md\:p-6 {
    padding: 1.5rem;
  }

  .md\:px-4 {
    padding-left: 1rem;
    padding-right: 1rem;
  }

  .md\:px-6 {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }

  .md\:py-6 {
    padding-top: 1.5rem;
    padding-bottom: 1.5rem;
  }

  .md\:text-left {
    text-align: left;
  }

  .md\:text-2xl {
    font-size: 1.5rem;
    line-height: 2rem;
  }

  .md\:text-base {
    font-size: 1rem;
    line-height: 1.5rem;
  }

  .md\:text-lg {
    font-size: 1.125rem;
    line-height: 1.75rem;
  }

  .md\:text-sm {
    font-size: 0.875rem;
    line-height: 1.25rem;
  }

  .md\:text-xl {
    font-size: 1.25rem;
    line-height: 1.75rem;
  }

  .md\:text-xs {
    font-size: 0.75rem;
    line-height: 1rem;
  }
}

.\[\&\>svg\]\:pointer-events-none>svg {
  pointer-events: none;
}

.\[\&\>svg\]\:size-3>svg {
  width: 0.75rem;
  height: 0.75rem;
}

.\[\&\>svg\]\:size-4>svg {
  width: 1rem;
  height: 1rem;
}

.\[\&\>svg\]\:translate-y-0\.5>svg {
  --tw-translate-y: 0.125rem;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.\[\&\>svg\]\:text-current>svg {
  color: currentColor;
}

.\[\&_p\]\:leading-relaxed p {
  line-height: 1.625;
}

.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*='size-']) {
  width: 1rem;
  height: 1rem;
}

.\[\&_svg\:not\(\[class\*\=\'text-\'\]\)\]\:text-muted-foreground svg:not([class*='text-']) {
  color: oklch(var(--muted-foreground));
}

.\[\&_svg\]\:pointer-events-none svg {
  pointer-events: none;
}

.\[\&_svg\]\:shrink-0 svg {
  flex-shrink: 0;
}

a.\[a\&\]\:hover\:bg-accent:hover {
  background-color: oklch(var(--accent));
}

a.\[a\&\]\:hover\:text-accent-foreground:hover {
  color: oklch(var(--accent-foreground));
}
