/* Buildr design system on Bootstrap 6: tokens, type, components, motion. Loaded after Bootstrap, before
   app.css and schemes.css. Rules sit in Bootstrap's `custom` layer (after components, before utilities),
   so utility classes still win. Colours derive from the base variables schemes.css sets. Logical
   properties only (Arabic-first). */

/* ---------- Fonts (outside layers) ---------- */
/* IBM Plex Sans, variable (wght 100-700), Latin subset; Arabic stays the two static faces. */
@font-face { font-family: "Plex Latin"; font-style: normal; font-weight: 100 700; font-display: swap; src: url("/static/fonts/ibm-plex-sans-latin-wght-normal.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Plex Arabic"; font-weight: 400; font-display: swap; src: url("/static/fonts/ibm-plex-sans-arabic-arabic-400-normal.woff2") format("woff2"); unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFF; }
@font-face { font-family: "Plex Arabic"; font-weight: 600; font-display: swap; src: url("/static/fonts/ibm-plex-sans-arabic-arabic-600-normal.woff2") format("woff2"); unicode-range: U+0600-06FF, U+0750-077F, U+FB50-FDFF, U+FE70-FEFF; }
/* Metric-matched local fallback (Plex: upm 1000, ascender 1025, descender 275, gap 0), so the swap
   from Arial/Helvetica to Plex moves nothing (CLS 0). Same Latin range, so Arabic never lands here. */
@font-face { font-family: "Plex Latin Fallback"; src: local("Arial"), local("ArialMT"), local("Helvetica Neue"), local("Helvetica"); size-adjust: 105.6%; ascent-override: 97.1%; descent-override: 26%; line-gap-override: 0%; unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+20AC, U+2122, U+2212; }

@layer custom {

/* ---------- 1. Tokens ---------- */
:root {
  --bs-body-font-family: "Plex Latin", "Plex Arabic", "Plex Latin Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Radii */
  --r-xs: .375rem; --r-sm: .5rem; --r-md: .75rem; --r-lg: 1rem; --r-xl: 1.375rem; --r-pill: 999px;
  /* Spacing rhythm, plus one fluid step between page blocks */
  --gap-2: .5rem; --gap-3: .75rem; --gap-4: 1rem; --gap-5: 1.5rem; --gap-6: 2rem;
  --gap-section: clamp(1rem, .7rem + 1.2vw, 1.75rem);
  /* Surfaces */
  --surface-raised: light-dark(var(--bs-bg-body), color-mix(in oklch, var(--bs-bg-body) 93%, var(--bs-fg-body)));
  --glass: color-mix(in oklch, var(--bs-bg-body) 72%, transparent);
  --glass-solid: color-mix(in oklch, var(--bs-bg-body) 96%, transparent);
  --overlay: light-dark(color-mix(in oklch, var(--bs-fg-body) 30%, transparent), oklch(0 0 0 / .58));
  --hairline: color-mix(in oklch, var(--bs-border-color) 75%, transparent);
  --tint: color-mix(in oklch, var(--bs-primary-base) 12%, transparent);
  --tint-strong: color-mix(in oklch, var(--bs-primary-base) 20%, transparent);
  --hover: color-mix(in oklch, var(--bs-fg-body) 5%, transparent);
  /* Elevation: layered, tinted by the text colour in light mode; deeper black plus a top light edge in dark */
  --sh-1: light-dark(color-mix(in oklch, var(--bs-fg-body) 6%, transparent), oklch(0 0 0 / .28));
  --sh-2: light-dark(color-mix(in oklch, var(--bs-fg-body) 9%, transparent), oklch(0 0 0 / .4));
  --sh-3: light-dark(color-mix(in oklch, var(--bs-fg-body) 14%, transparent), oklch(0 0 0 / .55));
  --edge: light-dark(transparent, color-mix(in oklch, var(--bs-fg-body) 7%, transparent));
  --e1: inset 0 1px 0 var(--edge), 0 1px 2px var(--sh-1);
  --e2: inset 0 1px 0 var(--edge), 0 1px 2px var(--sh-1), 0 4px 12px -4px var(--sh-2);
  --e3: inset 0 1px 0 var(--edge), 0 2px 4px var(--sh-1), 0 12px 32px -10px var(--sh-3);
  --e4: inset 0 1px 0 var(--edge), 0 4px 8px var(--sh-1), 0 24px 56px -16px var(--sh-3);
  /* Focus */
  --focus-c: color-mix(in oklch, var(--bs-primary-base) 75%, var(--bs-bg-body));
  --focus-w: 2px;
  --focus-ring: 0 0 0 3px color-mix(in oklch, var(--bs-primary-base) 30%, transparent);
  /* Motion */
  --dur-1: 110ms; --dur-2: 180ms; --dur-3: 300ms; --dur-4: 480ms;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
  --ease-spring: cubic-bezier(.34, 1.4, .64, 1);
  --ease-snappy: cubic-bezier(.2, .9, .3, 1.1);
  --app-nav-h: 3.5rem;
  /* Bootstrap knobs */
  --bs-body-font-size: clamp(1rem, .97rem + .12vw, 1.0625rem);
  --bs-body-line-height: 1.55;
  --bs-heading-font-weight: 620;
  --bs-heading-line-height: 1.2;
  --bs-font-size-lg: clamp(1.0625rem, 1rem + .3vw, 1.1875rem);
  --bs-font-size-xl: clamp(1.25rem, 1.1rem + .55vw, 1.5rem);
  --bs-font-size-2xl: clamp(1.5rem, 1.25rem + .9vw, 1.875rem);
  --bs-font-size-3xl: clamp(1.75rem, 1.4rem + 1.4vw, 2.375rem);
  --bs-font-size-4xl: clamp(2.125rem, 1.6rem + 2.2vw, 3rem);
  --bs-font-size-5xl: clamp(2.75rem, 1.9rem + 4vw, 4rem);
  --bs-focus-ring-width: var(--focus-w);
  --bs-focus-ring-color: var(--focus-c);
  --bs-border-color-translucent: var(--hairline);
  --bs-btn-input-border-radius: var(--r-sm);
  --bs-btn-input-sm-border-radius: var(--r-xs);
  --bs-btn-input-lg-border-radius: var(--r-md);
  --tracking-tight: -.022em; --tracking-snug: -.012em; --tracking-wide: .02em;
}
/* Arabic is cursive: no tracking, and Plex Arabic first. */
:root:lang(ar) {
  --bs-body-font-family: "Plex Arabic", "Plex Latin", "Plex Latin Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
  --tracking-tight: 0; --tracking-snug: 0; --tracking-wide: 0;
  --bs-body-line-height: 1.7;
}
@supports (transition-timing-function: linear(0, 1)) {
  :root {
    /* Gentle spring (small overshoot, settles fast) and a snappier one for presses */
    --ease-spring: linear(0, .009, .035 2.1%, .141 4.4%, .723 12.9%, .938 16.7%, 1.017 19.4%, 1.061 22%, 1.075 25.1%, 1.067 28.5%, 1.027 36.4%, 1.006 43.1%, .997 51%, 1.001 72%, 1);
    --ease-snappy: linear(0, .218 2.1%, .631 6.5%, .862 10.4%, .951 13.2%, 1.004 16.4%, 1.024 19.3%, 1.026 22.6%, 1.017 27.4%, .999 37.6%, .997 44.4%, 1);
  }
}
/* Scheme-aware theme colours: schemes.css sets only *-base, so derive primary and danger from it
   (Bootstrap's own shade formulas, with text colours clamped for contrast, and a contrast colour that
   flips to black on light primaries). Secondary/accent keep Bootstrap's neutrals: in the tweakcn
   schemes they are surface tints, not action colours. */
@supports (color: oklch(from red l c h)) {
  :root {
    --bs-primary-bg: var(--bs-primary-base);
    --bs-primary-fg: light-dark(oklch(from var(--bs-primary-base) min(l, .52) c h), oklch(from var(--bs-primary-base) max(l, .72) c h));
    --bs-primary-bg-subtle: light-dark(color-mix(in oklch, #fff 84%, var(--bs-primary-base)), color-mix(in oklch, #000 64%, var(--bs-primary-base)));
    --bs-primary-border: light-dark(color-mix(in oklch, #fff 40%, var(--bs-primary-base)), color-mix(in oklch, #000 16%, var(--bs-primary-base)));
    --bs-primary-focus-ring: light-dark(color-mix(in oklch, var(--bs-primary-base) 50%, var(--bs-bg-body)), color-mix(in oklch, var(--bs-primary-base) 75%, var(--bs-bg-body)));
    --bs-primary-contrast: oklch(from var(--bs-primary-base) clamp(0, (.7 - l) * 100, 1) 0 0);
    --bs-danger-bg: var(--bs-danger-base);
    --bs-danger-fg: light-dark(oklch(from var(--bs-danger-base) min(l, .52) c h), oklch(from var(--bs-danger-base) max(l, .72) c h));
    --bs-danger-bg-subtle: light-dark(color-mix(in oklch, #fff 84%, var(--bs-danger-base)), color-mix(in oklch, #000 64%, var(--bs-danger-base)));
    --bs-danger-border: light-dark(color-mix(in oklch, #fff 40%, var(--bs-danger-base)), color-mix(in oklch, #000 16%, var(--bs-danger-base)));
    --bs-danger-contrast: oklch(from var(--bs-danger-base) clamp(0, (.7 - l) * 100, 1) 0 0);
  }
}

/* Reduced motion: everything near-instant, view transitions off. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
}

/* ---------- 2. Base and typography ---------- */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scrollbar-gutter: stable; scroll-padding-block-start: calc(var(--app-nav-h) + .75rem); }
body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-kerning: normal; font-optical-sizing: auto; }
h1, .h1, h2, .h2, h3, .h3, h4, .h4, h5, .h5, h6, .h6 { text-wrap: balance; color: var(--bs-heading-color, var(--bs-fg-body)); }
h1, .h1, h2, .h2, .display-1, .display-2, .display-3, .display-4, .display-5, .display-6 { letter-spacing: var(--tracking-tight); }
h3, .h3, h4, .h4 { letter-spacing: var(--tracking-snug); }
h5, .h5, h6, .h6 { font-weight: 600; }
p, li, dd, blockquote, figcaption, .form-text { text-wrap: pretty; }
table, .tabular-nums, time, .badge, .font-monospace { font-variant-numeric: tabular-nums; }
a { text-underline-offset: .2em; text-decoration-thickness: from-font; }
::selection { background: var(--tint-strong); color: inherit; }
:focus-visible { outline: var(--focus-w) solid var(--focus-c); outline-offset: 2px; }
.form-control:focus-visible, .form-select:focus-visible, .form-check-input:focus-visible { outline-offset: 1px; }

/* Scrollbars: thin and themed */
* { scrollbar-width: thin; scrollbar-color: color-mix(in oklch, var(--bs-fg-body) 24%, transparent) transparent; }

/* ---------- 3. Shell ---------- */
#app-nav {
  --bs-navbar-min-height: var(--app-nav-h);
  --bs-navbar-brand-font-weight: 650;
  --bs-navbar-color: var(--bs-fg-2);
  --bs-nav-link-hover-bg: var(--hover);
  isolation: isolate;
}
#app-nav .navbar-brand { letter-spacing: var(--tracking-snug); }
#app-nav .nav-link { border-radius: var(--r-pill); }

aside:has(> .nav-pills) { padding-inline: .5rem; }
aside > .nav-pills {
  --bs-nav-pills-bg: transparent;
  --bs-nav-pills-padding: 0;
  --bs-nav-link-hover-bg: var(--hover);
  --bs-nav-link-color: var(--bs-fg-2);
  --bs-nav-link-hover-color: var(--bs-fg-body);
  --bs-nav-link-padding-y: .5rem;
  --bs-nav-pills-link-border-radius: var(--r-sm);
  --bs-nav-pills-link-active-bg: var(--tint);
  --bs-nav-pills-link-active-color: var(--bs-primary-fg);
  display: flex; gap: 1px; border-radius: 0;
}
aside > .nav-pills .nav-link { justify-content: flex-start; font-size: var(--bs-font-size-sm); }
aside > .nav-pills .nav-link.active { background-image: none; font-weight: 600; box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--bs-primary-base) 14%, transparent); }
@media (min-width: 768px) {
  aside > .nav-pills { position: sticky; inset-block-start: calc(var(--app-nav-h) + .75rem); max-block-size: calc(100dvh - var(--app-nav-h) - 1.5rem); overflow-y: auto; overscroll-behavior: contain; flex-wrap: nowrap; }
}

#main { container: main / inline-size; }
#breadcrumbs .breadcrumb { margin-block-end: var(--gap-4); font-size: var(--bs-font-size-sm); --bs-breadcrumb-link-padding-x: .5rem; --bs-breadcrumb-link-border-radius: var(--r-pill); --bs-breadcrumb-link-hover-bg: var(--hover); }
.breadcrumb-item.active { color: var(--bs-fg-1); font-weight: 500; }

/* ---------- 4. Components ---------- */
/* Buttons */
.btn {
  --bs-btn-font-weight: 550;
  --bs-btn-border-radius: var(--r-sm);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
:lang(ar) .btn { --bs-btn-font-weight: 600; }
.btn-solid { box-shadow: var(--e1), inset 0 1px 0 color-mix(in oklch, #fff 16%, transparent); }
.btn-outline { --bs-btn-border-color: color-mix(in oklch, var(--bs-theme-border, var(--bs-border-color)) 80%, transparent); }
.btn-sm { --bs-btn-border-radius: var(--r-xs); }
.btn-lg { --bs-btn-border-radius: var(--r-md); }
@media (prefers-reduced-motion: no-preference) {
  .btn { transition: color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out), transform var(--dur-3) var(--ease-snappy); }
  .btn:active:not(:disabled, .disabled) { transform: scale(.97); transition-duration: 60ms; }
}
@media (pointer: coarse) {
  .btn, .form-control, .form-select, .nav-link, .menu-item, .page-link, .breadcrumb-link { min-block-size: 2.75rem; }
  .btn-sm { --bs-btn-padding-x: .875rem; }
  .form-check-input { inline-size: 1.25rem; block-size: 1.25rem; }
}

/* Cards */
.card {
  --bs-card-border-radius: var(--r-lg);
  --bs-card-border-color: var(--hairline);
  --bs-card-box-shadow: var(--e1);
  --bs-card-bg: var(--surface-raised);
  --bs-card-cap-bg: transparent;
}
.card-header { border-block-end-color: var(--hairline); font-weight: 600; }
.card-footer { border-block-start-color: var(--hairline); }
.card-title { letter-spacing: var(--tracking-snug); }
.row > :not([class*="auto"]) > .card { container-type: inline-size; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  a.card, .card:has(.stretched-link) { transition: transform var(--dur-3) var(--ease-spring), box-shadow var(--dur-3) var(--ease-out); }
  a.card:hover, .card:has(.stretched-link):hover { transform: translateY(-2px); box-shadow: var(--e3); }
}

/* List groups */
.list-group { --bs-list-group-border-color: var(--hairline); --bs-list-group-border-radius: var(--r-md); --bs-list-group-bg: var(--surface-raised); --bs-list-group-action-hover-bg: var(--hover); }
#main .list-group > .list-group-item:nth-child(n+30) { content-visibility: auto; contain-intrinsic-size: auto 3.25rem; }

/* Tables */
.table {
  --bs-table-cell-padding-y: .625rem;
  --bs-table-cell-padding-x: .75rem;
  --bs-table-border-color: var(--hairline);
  --bs-table-bg: transparent;
  --bs-table-hover-bg-factor: 4%;
  --bs-table-striped-bg-factor: 2.5%;
}
.table > thead > tr > * {
  position: sticky; inset-block-start: 0; z-index: 1;
  background-color: color-mix(in oklch, var(--bs-bg-2) 85%, var(--bs-bg-body));
  color: var(--bs-fg-2); font-size: var(--bs-font-size-sm); font-weight: 600; letter-spacing: var(--tracking-wide);
  white-space: nowrap; vertical-align: bottom; border-block-end-color: var(--bs-border-color);
}
.table > tbody > tr:nth-child(even) > * { --bs-table-bg-type: color-mix(in oklch, var(--bs-fg-body) 2.2%, transparent); }
.table > tbody > tr:last-child > * { border-block-end-width: 0; }
.table-hover > tbody > tr { transition: background-color var(--dur-1) linear; }
.table-responsive { border: 1px solid var(--hairline); border-radius: var(--r-md); background: var(--surface-raised); box-shadow: var(--e1); margin-block-end: var(--gap-section); }
.table-responsive > .table { margin-block-end: 0; }
.card .table-responsive, .table-responsive.border-0 { border: 0; box-shadow: none; border-radius: 0; background: transparent; margin-block-end: 0; }
@container (max-width: 36rem) {
  .table { --bs-table-cell-padding-x: .5rem; --bs-table-cell-padding-y: .5rem; font-size: var(--bs-font-size-sm); }
  .table > thead > tr > * { font-size: var(--bs-font-size-xs); }
}

/* Plain definition lists: a two-column grid; div-wrapped dt/dd pairs join it through subgrid */
dl:not([class]) { display: grid; grid-template-columns: minmax(8rem, max-content) 1fr; gap: var(--gap-2) var(--gap-4); }
dl:not([class]) > dt { color: var(--bs-fg-2); font-weight: 500; }
dl:not([class]) > dd { margin: 0; }
dl:not([class]) > div { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; }
@container main (max-width: 30rem) { dl:not([class]) { grid-template-columns: 1fr; } dl:not([class]) > dd { margin-block-end: var(--gap-2); } }

/* Forms */
.form-control, .form-select {
  --bs-control-bg: color-mix(in oklch, var(--bs-bg-2) 55%, var(--bs-bg-body));
  --bs-control-border-color: color-mix(in oklch, var(--bs-border-color) 90%, transparent);
  --bs-control-border-radius: var(--r-sm);
  --bs-control-box-shadow: none;
  --bs-control-placeholder-color: color-mix(in oklch, var(--bs-fg-3) 85%, transparent);
}
.form-control:hover:not(:focus, :disabled), .form-select:hover:not(:focus, :disabled) { --bs-control-border-color: color-mix(in oklch, var(--bs-fg-body) 22%, transparent); }
.form-control:focus, .form-select:focus { --bs-control-bg: var(--bs-bg-body); --bs-control-border-color: var(--focus-c); box-shadow: var(--focus-ring); outline-color: transparent; }
@media (prefers-reduced-motion: no-preference) {
  .form-control, .form-select { transition: border-color var(--dur-2) var(--ease-out), background-color var(--dur-2) var(--ease-out), box-shadow var(--dur-2) var(--ease-out); }
}
.form-label { font-weight: 500; font-size: var(--bs-font-size-sm); color: var(--bs-fg-1); margin-block-end: .375rem; }
.form-text { color: var(--bs-fg-3); }
.form-control.is-invalid, .form-select.is-invalid, [data-bs-validate] :is(.form-control, .form-select):user-invalid {
  --bs-control-border-color: var(--bs-danger-border);
  --bs-control-bg: color-mix(in oklch, var(--bs-danger-base) 6%, var(--bs-bg-body));
}
.form-control.is-invalid:focus, .form-select.is-invalid:focus { box-shadow: 0 0 0 3px color-mix(in oklch, var(--bs-danger-base) 28%, transparent); --bs-control-border-color: var(--bs-danger-base); }
.form-control.is-valid, .form-select.is-valid { --bs-control-border-color: color-mix(in oklch, var(--bs-success-base) 60%, var(--bs-border-color)); }
.invalid-feedback { font-size: var(--bs-font-size-sm); }
.form-check-input { border-color: color-mix(in oklch, var(--bs-fg-body) 28%, transparent); }
@media (prefers-reduced-motion: no-preference) {
  .form-check-input { transition: background-color var(--dur-2) var(--ease-out), border-color var(--dur-2) var(--ease-out), transform var(--dur-3) var(--ease-snappy); }
  .form-check-input:active { transform: scale(.9); }
}

/* Menus */
.menu {
  --bs-menu-bg: var(--surface-raised);
  --bs-menu-border-color: var(--hairline);
  --bs-menu-border-radius: var(--r-md);
  --bs-menu-box-shadow: var(--e3);
  --bs-menu-padding-x: .375rem;
  --bs-menu-padding-y: .375rem;
  --bs-menu-item-border-radius: var(--r-xs);
  --bs-menu-item-padding-y: .4375rem;
  --bs-menu-item-hover-bg: var(--hover);
  --bs-menu-item-active-bg: var(--tint);
  --bs-menu-item-active-color: var(--bs-primary-fg);
  --bs-menu-transition-duration: var(--dur-3);
  --bs-menu-transition-timing: var(--ease-spring);
  transform-origin: top left;
}
[dir="rtl"] .menu { transform-origin: top right; }

/* Badges, alerts, toasts */
.badge { --bs-badge-border-radius: var(--r-pill); --bs-badge-padding-x: .6em; letter-spacing: .01em; }
.alert { --bs-alert-border-radius: var(--r-md); --bs-alert-border-color: var(--hairline); --bs-alert-padding-y: .875rem; text-wrap: pretty; }
.alert[class*="theme-"] { border-color: color-mix(in oklch, var(--bs-theme-border) 55%, transparent); }
.toast { --bs-toast-border-radius: var(--r-md); --bs-toast-box-shadow: var(--e3); --bs-toast-bg: var(--surface-raised); --bs-toast-border-color: var(--hairline); }
#toasts { z-index: var(--bs-z-toast); display: grid; gap: var(--gap-2); }
.perceived-toasts { position: fixed; inset-block-end: max(1rem, env(safe-area-inset-bottom)); inset-inline-end: 1rem; z-index: var(--bs-z-toast); display: grid; gap: var(--gap-2); max-inline-size: min(24rem, calc(100vw - 2rem)); }
.perceived-toast {
  display: flex; align-items: center; justify-content: space-between; gap: var(--gap-3);
  padding: .75rem 1rem; border-radius: var(--r-md); border: 1px solid var(--hairline);
  background: var(--surface-raised); color: var(--bs-fg-body); box-shadow: var(--e3);
  font-size: var(--bs-font-size-sm); animation: toast-in var(--dur-4) var(--ease-spring) both;
}
.perceived-toast.is-error { border-color: var(--bs-danger-border); background: color-mix(in oklch, var(--bs-danger-base) 8%, var(--surface-raised)); border-inline-start: 3px solid var(--bs-danger-base); }
@keyframes toast-in { from { opacity: 0; transform: translateY(.75rem) scale(.96); } }

/* Dialogs: Bootstrap .dialog via its variables; plain <dialog> (and .confirm-dialog) here */
dialog:not(.dialog) {
  border: 1px solid var(--hairline); border-radius: var(--r-xl); background: var(--surface-raised); color: var(--bs-fg-body);
  box-shadow: var(--e4); padding: 1.25rem; max-inline-size: min(32rem, calc(100vw - 2rem));
}
dialog:not(.dialog)[open] { animation: dialog-in var(--dur-3) var(--ease-spring) both; }
dialog:not(.dialog)::backdrop { background: var(--overlay); }
.dialog { --bs-dialog-border-radius: var(--r-xl); --bs-dialog-box-shadow: var(--e4); --bs-dialog-bg: var(--surface-raised); --bs-dialog-backdrop-bg: var(--overlay); }
@supports (backdrop-filter: blur(1px)) {
  dialog:not(.dialog)::backdrop { backdrop-filter: blur(6px); }
}
@keyframes dialog-in { from { opacity: 0; transform: translateY(.5rem) scale(.97); } }

/* Skeletons and loading */
.placeholder { --bs-placeholder-opacity-max: .1; --bs-placeholder-opacity-min: .05; border-radius: var(--r-xs); background-color: var(--bs-fg-body); }
.perceived-skeleton { padding-block: var(--gap-2); }
.skeleton {
  display: block; min-block-size: 1em; border-radius: var(--r-xs);
  background: linear-gradient(90deg, var(--bs-bg-2) 25%, var(--bs-bg-3) 50%, var(--bs-bg-2) 75%) 0 0 / 300% 100%;
  animation: shimmer 1.4s linear infinite;
}
@keyframes shimmer { to { background-position: -150% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }
.is-stale { opacity: .7; transition: opacity var(--dur-2) linear; }

/* The htmx progress bar (client/page/perceived.ts sets the width inline) */
.perceived-bar {
  position: fixed; inset-block-start: 0; inset-inline-start: 0; z-index: calc(var(--bs-z-toast) + 1);
  block-size: 3px; inline-size: 0; pointer-events: none; opacity: 0;
  background: var(--bs-primary-base); border-end-end-radius: 3px; border-start-end-radius: 3px;
  box-shadow: 0 0 10px color-mix(in oklch, var(--bs-primary-base) 60%, transparent);
  transition: inline-size var(--dur-3) var(--ease-out), opacity var(--dur-2) linear;
}
.perceived-bar.is-on { opacity: 1; }
.perceived-bar.is-done { opacity: 0; transition: inline-size var(--dur-2) var(--ease-out), opacity var(--dur-3) linear var(--dur-2); }

/* Empty states: the `text-center fg-2 py-12` block the views use, plus an explicit .empty-state */
.empty-state, div.text-center.fg-2.py-12 {
  border: 1px dashed color-mix(in oklch, var(--bs-border-color) 90%, transparent); border-radius: var(--r-lg);
  background: color-mix(in oklch, var(--bs-bg-2) 40%, transparent); color: var(--bs-fg-2); text-wrap: balance;
}
.empty-state { padding: var(--gap-6) var(--gap-4); text-align: center; }

/* ---------- 5. Scroll-driven motion (CSS only) ---------- */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    #app-nav::before, #app-nav::after { content: ""; position: absolute; pointer-events: none; opacity: 0; animation: fade-in linear both; animation-timeline: scroll(root block); animation-range: 0 5rem; }
    #app-nav::before { inset: 0; z-index: -1; background: var(--bs-bg-body); --to: .55; }
    #app-nav::after { inset-inline: 0; inset-block-start: 100%; block-size: .75rem; background: linear-gradient(var(--sh-2), transparent); }
    @media (pointer: fine) {
      #main .row > * > .card, #main .list-group > .list-group-item { animation: rise linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
    }
  }
}
@keyframes fade-in { to { opacity: var(--to, 1); } }
@keyframes rise { from { opacity: 0; translate: 0 .75rem; } }

/* ---------- 6. View transitions ---------- */
#app-nav { view-transition-name: app-nav; }
aside:has(> .nav-pills) { view-transition-name: app-side; }
#main { view-transition-name: app-main; }
/* The theme/scheme circle reveal (schemes.css) must capture the whole page as root. */
html.reveal #app-nav, html.reveal #main, html.reveal aside { view-transition-name: none; }
html:not(.reveal)::view-transition-old(root), html:not(.reveal)::view-transition-new(root) { animation-duration: var(--dur-2); }
::view-transition-group(app-nav), ::view-transition-group(app-side), ::view-transition-group(app-main) { animation: none; }
::view-transition-old(app-nav), ::view-transition-old(app-side) { animation: none; opacity: 0; }
::view-transition-new(app-nav), ::view-transition-new(app-side) { animation: none; }
::view-transition-old(app-main) { animation: vt-out var(--dur-2) var(--ease-out) both; }
::view-transition-new(app-main) { animation: vt-in var(--dur-3) var(--ease-out) both; }
@keyframes vt-out { to { opacity: 0; translate: 0 -.25rem; } }
@keyframes vt-in { from { opacity: 0; translate: 0 .5rem; } }

} /* @layer custom */

/* ---------- Unlayered: the shell's utility classes (bg-body, border-*) would otherwise win ---------- */
#app-nav { background-color: var(--glass-solid); border-block-end-color: var(--hairline); }
@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
  #app-nav { background-color: var(--glass); -webkit-backdrop-filter: saturate(170%) blur(16px); backdrop-filter: saturate(170%) blur(16px); }
}
/* Opaque where blur is unwanted or costly: reduced transparency, and small touch screens that are not iOS. */
@media (prefers-reduced-transparency: reduce) {
  #app-nav { background-color: var(--bs-bg-body); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@supports not (-webkit-touch-callout: none) {
  @media (pointer: coarse) and (max-width: 40rem) {
    #app-nav { background-color: var(--glass-solid); -webkit-backdrop-filter: none; backdrop-filter: none; }
  }
}
aside:has(> .nav-pills) { background-color: transparent; border-inline-end-color: var(--hairline); }

/* Cross-document navigations (non-boosted links) morph the same way. */
@media (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
}
