/* Freeday components — GENERATED by tokens/build.mjs. Do not edit by hand. */
/* Freeday base layer — reset ringan + default via token */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  color: var(--color-text);
  background: var(--color-surface);
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: var(--weight-bold); letter-spacing: var(--tracking-tighter); line-height: var(--leading-snug); margin: 0; }
a { color: var(--color-primary); }
:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring); outline-offset: var(--focus-ring-width); border-radius: var(--radius-xs); }
:where(button, input, select, textarea) { font: inherit; }
.fdy-visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
/* Opt-in list reset. base.css is intentionally a *light* reset — it does NOT strip list/paragraph
 * margins (see the kit's own list components, which each reset themselves). If you run a utility
 * framework with its preflight OFF (the recommended pairing), a semantic <ul>/<ol> keeps native
 * bullets + a 40px indent; add this class (or a Freeday list component) to normalise it. */
.fdy-list-reset { list-style: none; margin: 0; padding: 0; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* Freeday — Accordion (native <details>/<summary>, zero-JS) */
.fdy-accordion{border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);overflow:hidden;background:var(--color-surface);}
.fdy-accordion__item + .fdy-accordion__item{border-top:var(--bw) solid var(--color-border);}
.fdy-accordion__item > summary{list-style:none;cursor:pointer;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);font-weight:var(--weight-medium);color:var(--color-text);}
.fdy-accordion__item > summary::-webkit-details-marker{display:none;}
.fdy-accordion__item > summary::after{content:"";margin-left:auto;margin-top:-.15rem;flex:none;width:.5rem;height:.5rem;border-right:2px solid var(--color-text-subtle);border-bottom:2px solid var(--color-text-subtle);transform:rotate(45deg);transition:transform var(--dur-fast) var(--ease-standard);}
.fdy-accordion__item[open] > summary::after{transform:rotate(225deg);margin-top:.1rem;}
.fdy-accordion__item > summary:hover{background:var(--color-surface-2);}
.fdy-accordion__item > summary:focus-visible{outline:none;box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
.fdy-accordion__panel{padding:0 var(--space-4) var(--space-4);color:var(--color-text-muted);font-size:var(--text-sm);line-height:var(--leading-normal);}
/* Content reveal on open (fade + rise). Native <details> can't animate its own height cross-
 * browser without JS, so we animate the revealed panel instead — cheap, safe, reduced-motion gated. */
@media (prefers-reduced-motion:no-preference){.fdy-accordion__item[open] > .fdy-accordion__panel{animation:fdy-combo-in var(--dur-base) var(--ease-standard);}}

/* Freeday — Alert (inline) */
.fdy-alert{display:flex;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);border:var(--bw) solid var(--color-border);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface-2);}
.fdy-alert__icon{flex:none;display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;margin-top:.05rem;}
.fdy-alert__icon svg{width:100%;height:100%;}
.fdy-alert__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1);}
.fdy-alert__title{font-weight:var(--weight-semibold);color:var(--color-text);}
.fdy-alert__text{color:var(--color-text);line-height:var(--leading-normal);}
.fdy-alert__close{flex:none;align-self:flex-start;border:0;background:transparent;color:var(--color-text-muted);cursor:pointer;font-size:var(--text-lg);line-height:1;padding:0 var(--space-1);border-radius:var(--radius-sm);}
.fdy-alert__close:hover{color:var(--color-text);}
.fdy-alert__close:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-alert--info{background:var(--color-info-soft);border-color:color-mix(in srgb,var(--color-info) 26%,transparent);}
.fdy-alert--info .fdy-alert__title,.fdy-alert--info .fdy-alert__icon{color:var(--color-info-strong);}
.fdy-alert--success{background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
.fdy-alert--success .fdy-alert__title,.fdy-alert--success .fdy-alert__icon{color:var(--color-success-strong);}
.fdy-alert--warning{background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
.fdy-alert--warning .fdy-alert__title,.fdy-alert--warning .fdy-alert__icon{color:var(--color-warning-strong);}
.fdy-alert--danger{background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
.fdy-alert--danger .fdy-alert__title,.fdy-alert--danger .fdy-alert__icon{color:var(--color-danger-strong);}

/* Freeday — App Shell.
 * Natural document scroll: the shell grows with content and the PAGE scrolls,
 * while the sidebar and topbar are position:sticky so they stay in view. No
 * fixed-height / internal-scroll trickery (that leaves a white gap if the host
 * page can still scroll). Structure: .fdy-app > (.fdy-app__sidebar, .fdy-app__content
 * > (.fdy-app__topbar, .fdy-app__main)). The __content wrapper gives the sticky
 * topbar a tall containing block so it can travel — a bare grid cell can't. */
.fdy-app{display:flex;align-items:stretch;min-height:100vh;background:var(--color-surface-2);}
.fdy-app__sidebar{position:sticky;top:0;align-self:flex-start;height:100vh;overflow:hidden;flex:none;width:15.5rem;box-sizing:border-box;background:var(--color-surface);border-right:var(--bw) solid var(--color-border);display:flex;flex-direction:column;transition:width var(--dur-slow) var(--ease-standard),border-right-width var(--dur-slow) var(--ease-standard);}
.fdy-app__content{flex:1;min-width:0;display:flex;flex-direction:column;}
/* Brand is a fixed header — same height as the topbar so they align, and only
 * the nav below it scrolls. Bare text (no children) renders as one bold
 * display line via the rules on .fdy-app__brand itself. For a mark + two-line
 * title/subtitle, add structured children mirroring .fdy-appbar__brand:
 * <div class="fdy-app__brand"><svg class="fdy-app__brand-mark">…</svg>
 *   <div class="fdy-app__brand-text">
 *     <span class="fdy-app__brand-title">…</span>
 *     <span class="fdy-app__brand-subtitle">…</span>
 *   </div></div> */
.fdy-app__brand{flex:none;display:flex;align-items:center;gap:var(--space-2);box-sizing:border-box;min-height:var(--space-16);font-family:var(--font-display);font-weight:var(--weight-bold);font-size:var(--text-lg);color:var(--color-text);text-decoration:none;padding:0 var(--space-4);border-bottom:var(--bw) solid var(--color-border);}
.fdy-app__brand-mark{flex:none;width:1.5rem;height:1.5rem;}
.fdy-app__brand-mark svg{display:block;width:100%;height:100%;}
.fdy-app__brand-text{display:flex;flex-direction:column;min-width:0;}
.fdy-app__brand-title{display:block;font-family:var(--font-display);font-weight:var(--weight-bold);font-size:var(--text-lg);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-app__brand-subtitle{display:block;font-size:var(--text-xs);font-weight:var(--weight-regular);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-nav{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;display:flex;flex-direction:column;gap:2px;padding:var(--space-3) var(--space-3) var(--space-6);}
.fdy-nav__item{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted);text-decoration:none;cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
.fdy-nav__item:hover{background:var(--color-surface-2);color:var(--color-text);}
/* Active indicator stays in the primary ramp so it never clashes with a re-themed accent. */
.fdy-nav__item[aria-current="page"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
.fdy-nav__item:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
/* Sidebar-menu extras: per-node icon (leading), count badge (trailing), and a
 * text label that truncates. Any of these are optional — a bare text item works. */
.fdy-nav__icon{flex:none;display:inline-flex;width:1.15rem;height:1.15rem;}
.fdy-nav__icon svg{display:block;width:100%;height:100%;}
.fdy-nav__label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-nav__badge{flex:none;margin-left:auto;min-width:1.25rem;height:1.25rem;padding:0 6px;display:inline-flex;align-items:center;justify-content:center;font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;border-radius:var(--radius-full);background:var(--color-surface-3);color:var(--color-text-muted);}
.fdy-nav__item[aria-current="page"] .fdy-nav__badge{background:var(--color-primary);color:var(--color-on-primary);}
/* Collapsible section: <details class="fdy-nav__group"><summary class="fdy-nav__grouplabel"> */
.fdy-nav__group{margin:0;}
.fdy-nav__group + .fdy-nav__group,.fdy-nav__item + .fdy-nav__group{border-top:var(--bw) solid var(--color-border-muted);margin-top:var(--space-1);padding-top:var(--space-1);}
.fdy-nav__grouplabel{list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);padding:var(--space-3) var(--space-3) var(--space-1);font-size:var(--text-xs);text-transform:uppercase;letter-spacing:var(--tracking-wide);font-weight:var(--weight-semibold);color:var(--color-text-subtle);}
.fdy-nav__grouplabel::-webkit-details-marker{display:none;}
.fdy-nav__grouplabel:hover{color:var(--color-text-muted);}
.fdy-nav__grouplabel:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
.fdy-nav__grouplabel::after{content:"";flex:none;width:.45rem;height:.45rem;margin-right:var(--space-1);border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(-45deg);transition:transform var(--dur-fast) var(--ease-standard);opacity:.7;}
.fdy-nav__group[open] > .fdy-nav__grouplabel::after{transform:rotate(45deg);}
/* --flat: calmer, non-collapsible grouped nav — hide the caret, drop the
 * inter-group divider and the collapse cursor. Works on native <details> groups
 * (caret just hidden) and on static <div>/<p> groups (never collapsible). */
.fdy-nav--flat .fdy-nav__grouplabel::after{display:none;}
.fdy-nav--flat .fdy-nav__group + .fdy-nav__group,.fdy-nav--flat .fdy-nav__item + .fdy-nav__group{border-top:0;}
.fdy-nav--flat .fdy-nav__grouplabel{cursor:default;}
/* Collapsible item (nested tree): <details class="fdy-nav__tree"><summary class="fdy-nav__item"> */
.fdy-nav__tree{margin:0;}
.fdy-nav__tree > summary{list-style:none;}
.fdy-nav__tree > summary::-webkit-details-marker{display:none;}
.fdy-nav__tree > summary .fdy-nav__caret{flex:none;margin-left:auto;width:.4rem;height:.4rem;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(-45deg);transition:transform var(--dur-fast) var(--ease-standard);opacity:.6;}
.fdy-nav__tree[open] > summary .fdy-nav__caret{transform:rotate(45deg);}
.fdy-nav__sub{display:flex;flex-direction:column;gap:2px;padding-left:calc(var(--space-3) + 1.15rem);margin-top:2px;}
/* Collapse toggle (hamburger) — sits in the topbar; collapses the sidebar. */
.fdy-app__navtoggle{display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;flex:none;padding:0;border:0;border-radius:var(--radius-md);background:transparent;color:var(--color-text-muted);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
.fdy-app__navtoggle:hover{background:var(--color-surface-2);color:var(--color-text);}
.fdy-app__navtoggle:focus-visible{outline:none;box-shadow:0 0 0 2px var(--color-primary);}
.fdy-app__navtoggle svg{display:block;width:1.25rem;height:1.25rem;}
/* Desktop collapse: animate width -> 0 (content clips via overflow:hidden; the content area
 * flexes in to fill). Not display:none, so the collapse/expand slides instead of snapping. */
@media (min-width:721px){.fdy-app--nav-collapsed .fdy-app__sidebar{width:0;border-right-width:0;}}
.fdy-app__topbar{position:sticky;top:0;z-index:20;min-height:var(--space-16);display:flex;align-items:center;gap:var(--space-3);padding:0 var(--space-8);background:var(--color-surface);border-bottom:var(--bw) solid var(--color-border);}
.fdy-app__title{font-family:var(--font-display);font-size:var(--text-xl);font-weight:var(--weight-semibold);color:var(--color-text);margin:0 auto 0 0;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-app__main{flex:1;padding:var(--space-8);}
.fdy-skip{position:absolute;left:var(--space-2);top:var(--space-2);background:var(--color-primary);color:var(--color-on-primary);padding:var(--space-2) var(--space-4);border-radius:var(--radius-md);z-index:100;transform:translateY(-250%);transition:transform var(--dur-fast) var(--ease-standard);}
.fdy-skip:focus{transform:translateY(0);}
/* --static: for a bounded/embedded shell (a demo box, not the whole page) —
 * drop sticky so nothing escapes the box; sidebar stretches to fill it. */
.fdy-app--static .fdy-app__sidebar{position:static;height:auto;align-self:stretch;}
.fdy-app--static .fdy-app__topbar{position:static;}
/* Mobile: the sidebar becomes an off-canvas drawer opened by the topbar toggle. */
.fdy-app__backdrop{display:none;}
@media (max-width:720px){
  .fdy-app__sidebar{position:fixed;top:0;left:0;bottom:0;height:100dvh;width:16rem;z-index:60;transform:translateX(-100%);transition:transform var(--dur-base) var(--ease-standard);box-shadow:var(--shadow-4);}
  .fdy-app--nav-open .fdy-app__sidebar{transform:translateX(0);}
  .fdy-app__backdrop{display:block;position:fixed;inset:0;z-index:55;background:rgba(8,10,20,.45);opacity:0;visibility:hidden;transition:opacity var(--dur-base) var(--ease-standard),visibility var(--dur-base) var(--ease-standard);}
  .fdy-app--nav-open .fdy-app__backdrop{opacity:1;visibility:visible;}
  .fdy-app__main{padding:var(--space-5);}
  .fdy-app__topbar{padding:0 var(--space-4);}
}
@media (prefers-reduced-motion:reduce){.fdy-app__sidebar{transition:none;}}

/* Freeday — App bar (standalone top bar: brand · actions · spacer).
 * Distinct from .fdy-app__topbar (which is bound to the shell grid). Use anywhere;
 * sticky / elevated / dense / coloured via modifiers. Pure CSS. */
.fdy-appbar{display:flex;align-items:center;gap:var(--space-3);height:var(--space-16);padding:0 var(--space-4);background:var(--color-surface);color:var(--color-text);border-bottom:var(--bw) solid var(--color-border);}
.fdy-appbar--sticky{position:sticky;top:0;z-index:90;}
.fdy-appbar--elevated{border-bottom:0;box-shadow:var(--shadow-2);}
.fdy-appbar--dense{height:var(--space-12);}
.fdy-appbar--primary{background:var(--color-primary);color:var(--color-on-primary);border-bottom-color:transparent;}
.fdy-appbar__brand{display:inline-flex;align-items:center;gap:var(--space-2);font-family:var(--font-display);font-weight:var(--weight-bold);font-size:var(--text-lg);color:inherit;white-space:nowrap;}
.fdy-appbar__brand svg{display:block;width:1.5rem;height:1.5rem;}
.fdy-appbar__spacer{flex:1;}
.fdy-appbar__actions{display:inline-flex;align-items:center;gap:var(--space-1);}
/* Controls on a coloured app bar go on-colour (icons stay legible, hover is a light wash) */
.fdy-appbar--primary .fdy-btn--ghost{background:transparent;border-color:transparent;color:var(--color-on-primary);box-shadow:none;}
.fdy-appbar--primary .fdy-btn--ghost:hover{background:color-mix(in srgb,var(--color-on-primary) 16%,transparent);color:var(--color-on-primary);transform:none;}

/* Freeday — Autocomplete (text input + filtered suggestion listbox, APG editable combobox).
 * Enhanced by freeday-autocomplete.js. */
.fdy-autocomplete{position:relative;display:block;max-width:22rem;}
.fdy-autocomplete__listbox{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:120;min-width:100%;max-height:16rem;overflow-y:auto;margin:0;padding:var(--space-1);list-style:none;background:var(--color-surface);color:var(--color-text);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);}
.fdy-autocomplete__listbox[hidden]{display:none;}
.fdy-autocomplete__option{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;white-space:nowrap;}
.fdy-autocomplete__option[hidden]{display:none;}
.fdy-autocomplete__option:hover,.fdy-autocomplete__option.is-highlighted{background:var(--color-surface-3);}
.fdy-autocomplete__option[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
.fdy-autocomplete__empty{padding:var(--space-2) var(--space-3);font-size:var(--text-sm);color:var(--color-text-muted);}
.fdy-autocomplete__empty[hidden]{display:none;}
@media (prefers-reduced-motion:no-preference){.fdy-autocomplete__listbox:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}

/* Freeday — Avatar */
.fdy-avatar{display:inline-flex;align-items:center;justify-content:center;flex:none;width:2.5rem;height:2.5rem;border-radius:var(--radius-full);background:var(--color-primary-soft);color:var(--color-primary-strong);font-family:var(--font-body);font-weight:var(--weight-semibold);font-size:var(--text-sm);line-height:1;overflow:hidden;user-select:none;}
.fdy-avatar img{width:100%;height:100%;object-fit:cover;}
.fdy-avatar--sm{width:2rem;height:2rem;font-size:var(--text-xs);}
.fdy-avatar--lg{width:3.5rem;height:3.5rem;font-size:var(--text-lg);}
.fdy-avatar-group{display:inline-flex;}
.fdy-avatar-group .fdy-avatar{border:2px solid var(--color-surface);margin-left:calc(var(--space-2)*-1);}
.fdy-avatar-group .fdy-avatar:first-child{margin-left:0;}
/* Decorative identity tones — a soft tint of a categorical chart colour with a theme-aware,
 * text-leaning foreground so initials keep WCAG AA (verified >=4.5:1 in light & dark by
 * test/contrast.test.mjs). Use to disambiguate same-initial avatars (e.g. many "PT …" names):
 * hash a stable 1..8 index off the FULL name in your app, then apply .fdy-avatar--tone-<n>. */
.fdy-avatar--tone-1,.fdy-avatar--tone-2,.fdy-avatar--tone-3,.fdy-avatar--tone-4,.fdy-avatar--tone-5,.fdy-avatar--tone-6,.fdy-avatar--tone-7,.fdy-avatar--tone-8{background:color-mix(in srgb,var(--_fdy-avatar-tone) 18%,var(--color-surface));color:color-mix(in srgb,var(--_fdy-avatar-tone) 50%,var(--color-text));}
.fdy-avatar--tone-1{--_fdy-avatar-tone:var(--tone-1);}
.fdy-avatar--tone-2{--_fdy-avatar-tone:var(--tone-2);}
.fdy-avatar--tone-3{--_fdy-avatar-tone:var(--tone-3);}
.fdy-avatar--tone-4{--_fdy-avatar-tone:var(--tone-4);}
.fdy-avatar--tone-5{--_fdy-avatar-tone:var(--tone-5);}
.fdy-avatar--tone-6{--_fdy-avatar-tone:var(--tone-6);}
.fdy-avatar--tone-7{--_fdy-avatar-tone:var(--tone-7);}
.fdy-avatar--tone-8{--_fdy-avatar-tone:var(--tone-8);}

/* Freeday — Badge */
.fdy-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;white-space:nowrap;padding:.35em .7em;border-radius:var(--radius-full);color:var(--color-primary-strong);background:var(--color-primary-soft);border:var(--bw) solid color-mix(in srgb,var(--color-primary) 22%,transparent);box-shadow:0 1px 1.5px rgba(16,14,30,.05);}
.fdy-badge--success{color:var(--color-success-strong);background:var(--color-success-soft);border-color:color-mix(in srgb,var(--color-success) 26%,transparent);}
.fdy-badge--warning{color:var(--color-warning-strong);background:var(--color-warning-soft);border-color:color-mix(in srgb,var(--color-warning) 26%,transparent);}
.fdy-badge--danger{color:var(--color-danger-strong);background:var(--color-danger-soft);border-color:color-mix(in srgb,var(--color-danger) 26%,transparent);}
.fdy-badge--info{color:var(--color-info-strong);background:var(--color-info-soft);border-color:color-mix(in srgb,var(--color-info) 26%,transparent);}
.fdy-badge--outline{background:transparent;border-color:var(--color-border-strong);color:var(--color-text-muted);box-shadow:none;}

/* Overlay badge — anchors a small count/dot/icon badge to a corner of any element
 * (icon, button, text). Wrap the content in .fdy-badge-wrap; add .fdy-badge-ov as a
 * sibling. Default is a solid neutral pill; colour + dot + position via modifiers. */
.fdy-badge-wrap{position:relative;display:inline-flex;vertical-align:middle;}
.fdy-badge-ov{position:absolute;top:0;right:0;transform:translate(50%,-50%);z-index:1;box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;min-width:1.25rem;height:1.25rem;padding:0 var(--space-1);border-radius:var(--radius-full);font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);line-height:1;white-space:nowrap;color:var(--color-inverse-text);background:var(--color-inverse-surface);border:2px solid var(--color-surface);}
.fdy-badge-ov svg{display:block;width:.75rem;height:.75rem;}
.fdy-badge-ov--dot{min-width:0;width:.75rem;height:.75rem;padding:0;}
/* Solid colours safe for count/text (on-* tokens, AA in light & dark) */
.fdy-badge-ov--primary{background:var(--color-primary);color:var(--color-on-primary);}
.fdy-badge-ov--danger{background:var(--color-danger-btn);color:var(--color-on-danger);}
/* Dot-oriented accents (for dots — plain text on these is not guaranteed AA) */
.fdy-badge-ov--accent{background:var(--color-accent);}
.fdy-badge-ov--info{background:var(--color-info);}
.fdy-badge-ov--success{background:var(--color-success);}
.fdy-badge-ov--warning{background:var(--color-warning);}
/* Anchor position */
.fdy-badge-ov--top-left{right:auto;left:0;transform:translate(-50%,-50%);}
.fdy-badge-ov--bottom-right{top:auto;bottom:0;transform:translate(50%,50%);}
.fdy-badge-ov--bottom-left{top:auto;bottom:0;right:auto;left:0;transform:translate(-50%,50%);}

/* Freeday — Breadcrumb */
.fdy-breadcrumb{font-size:var(--text-sm);}
.fdy-breadcrumb__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);list-style:none;margin:0;padding:0;}
.fdy-breadcrumb__item{display:inline-flex;align-items:center;gap:var(--space-2);color:var(--color-text-muted);}
.fdy-breadcrumb__link{color:var(--color-text-muted);text-decoration:none;border-radius:var(--radius-sm);}
.fdy-breadcrumb__link:hover{color:var(--color-primary-strong);text-decoration:underline;}
.fdy-breadcrumb__link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-breadcrumb__item[aria-current="page"]{color:var(--color-text);font-weight:var(--weight-medium);}
.fdy-breadcrumb__sep{color:var(--color-text-subtle);user-select:none;}

/* Freeday — Responsive display utilities (pairs with freeday-breakpoint.js).
 * Breakpoint scale (min-width, px): sm 600 · md 960 · lg 1280 · xl 1920.
 * NOTE: media-query breakpoints must be literal — CSS can't read custom properties
 * inside @media, so these px are structural, not stray magic numbers. */
.fdy-hidden{display:none !important;}

/* hide-below-X — hidden when the viewport is narrower than X (content shows at X and up) */
@media (max-width:599.98px){.fdy-hide-below-sm{display:none !important;}}
@media (max-width:959.98px){.fdy-hide-below-md{display:none !important;}}
@media (max-width:1279.98px){.fdy-hide-below-lg{display:none !important;}}

/* hide-above-X — hidden when the viewport is X and wider (content shows below X) */
@media (min-width:600px){.fdy-hide-above-sm{display:none !important;}}
@media (min-width:960px){.fdy-hide-above-md{display:none !important;}}
@media (min-width:1280px){.fdy-hide-above-lg{display:none !important;}}

/* Freeday — Button */
.fdy-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);
  height:var(--control-h);padding:0 var(--space-4);
  font-family:var(--font-body);font-size:var(--text-sm);font-weight:var(--weight-semibold);
  line-height:1;white-space:nowrap;cursor:pointer;text-decoration:none;color:var(--color-on-primary);
  background:linear-gradient(180deg,var(--color-primary),color-mix(in srgb,#000 10%,var(--color-primary)));
  border:var(--bw) solid transparent;border-radius:var(--radius-md);
  box-shadow:0 2px 9px -1px color-mix(in srgb,var(--color-primary) 50%,transparent),inset 0 1px 0 rgba(255,255,255,.26);
  transition:background var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-standard);}
.fdy-btn:hover{transform:translateY(-1px);box-shadow:0 6px 18px -2px color-mix(in srgb,var(--color-primary) 60%,transparent),inset 0 1px 0 rgba(255,255,255,.26);}
.fdy-btn:active{transform:translateY(1px);box-shadow:0 1px 4px -1px color-mix(in srgb,var(--color-primary) 46%,transparent);}
.fdy-btn:disabled{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none;}

.fdy-btn--ghost{background:var(--color-surface);color:var(--color-primary-strong);border-color:var(--color-border-strong);box-shadow:var(--shadow-1);}
.fdy-btn--ghost:hover{transform:none;background:var(--color-primary-soft);border-color:var(--color-primary-border);box-shadow:var(--shadow-1);}
.fdy-btn--ghost:active{transform:translateY(1px);}

.fdy-btn--danger{background:linear-gradient(180deg,var(--color-danger-btn),color-mix(in srgb,#000 12%,var(--color-danger-btn)));color:var(--color-on-danger);box-shadow:0 2px 9px -1px color-mix(in srgb,var(--color-danger-btn) 46%,transparent),inset 0 1px 0 rgba(255,255,255,.22);}
.fdy-btn--danger:hover{transform:translateY(-1px);box-shadow:0 6px 18px -2px color-mix(in srgb,var(--color-danger-btn) 54%,transparent),inset 0 1px 0 rgba(255,255,255,.22);}
.fdy-btn--danger:active{transform:translateY(1px);}

.fdy-btn--sm{height:calc(var(--control-h) - var(--space-2));padding:0 var(--space-3);font-size:var(--text-xs);border-radius:var(--radius-sm);}
.fdy-btn--lg{height:calc(var(--control-h) + var(--space-2));padding:0 var(--space-6);font-size:var(--text-base);border-radius:var(--radius-lg);}

/* Icon inside a button — scales with the button's font size (works for text+icon & icon-only) */
.fdy-btn__icon{display:inline-flex;flex:none;}
.fdy-btn__icon svg{display:block;width:1.15em;height:1.15em;}

/* Text button — lowest emphasis (no fill/border), colored label, subtle hover tint */
.fdy-btn--text{background:none;color:var(--color-primary-strong);border-color:transparent;box-shadow:none;}
.fdy-btn--text:hover{transform:none;background:var(--color-primary-soft);box-shadow:none;}
.fdy-btn--text:active{transform:translateY(1px);box-shadow:none;}

/* Icon-only — square; combine with --ghost/--text/--sm/--lg. Requires aria-label. */
.fdy-btn--icon{width:var(--control-h);padding:0;}
.fdy-btn--icon.fdy-btn--sm{width:calc(var(--control-h) - var(--space-2));}
.fdy-btn--icon.fdy-btn--lg{width:calc(var(--control-h) + var(--space-2));}

/* Button group — segmented, joined borders, rounded only at the ends */
.fdy-btn-group{display:inline-flex;}
.fdy-btn-group .fdy-btn{border-radius:0;}
.fdy-btn-group .fdy-btn:not(:first-child){margin-left:calc(var(--bw) * -1);}
.fdy-btn-group .fdy-btn:hover,.fdy-btn-group .fdy-btn:focus-visible{z-index:1;}
.fdy-btn-group .fdy-btn:first-child{border-top-left-radius:var(--radius-md);border-bottom-left-radius:var(--radius-md);}
.fdy-btn-group .fdy-btn:last-child{border-top-right-radius:var(--radius-md);border-bottom-right-radius:var(--radius-md);}

/* FAB — circular elevated action button (icon), optional extended pill with label */
.fdy-fab{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);width:3.5rem;height:3.5rem;padding:0;border:var(--bw) solid transparent;border-radius:var(--radius-full);cursor:pointer;color:var(--color-on-primary);background:linear-gradient(180deg,var(--color-primary),color-mix(in srgb,#000 10%,var(--color-primary)));box-shadow:var(--shadow-3);transition:transform var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
.fdy-fab:hover{transform:translateY(-1px);box-shadow:var(--shadow-4);}
.fdy-fab:active{transform:translateY(1px);}
.fdy-fab:focus-visible{border-radius:var(--radius-full);}
.fdy-fab:disabled{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none;}
.fdy-fab svg{display:block;width:1.5rem;height:1.5rem;}
.fdy-fab--sm{width:2.5rem;height:2.5rem;}
.fdy-fab--sm svg{width:1.25rem;height:1.25rem;}
.fdy-fab--extended{width:auto;padding:0 var(--space-5);font-family:var(--font-body);font-size:var(--text-sm);font-weight:var(--weight-semibold);}
.fdy-fab--danger{background:linear-gradient(180deg,var(--color-danger-btn),color-mix(in srgb,#000 12%,var(--color-danger-btn)));color:var(--color-on-danger);}
.fdy-fab--accent{background:linear-gradient(180deg,var(--color-accent),color-mix(in srgb,#000 10%,var(--color-accent)));color:var(--color-on-accent);}

/* Freeday — Card */
.fdy-card{background:var(--color-surface);border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-lift);transition:box-shadow var(--dur-base) var(--ease-standard),transform var(--dur-base) var(--ease-standard);}
.fdy-card--elevated{box-shadow:var(--shadow-lift-hover);}
.fdy-card--interactive{cursor:pointer;}
.fdy-card--interactive:hover{box-shadow:var(--shadow-lift-hover);transform:translateY(-3px);}
/* The global reduced-motion reset kills the ANIMATION; drop the -3px shift too so the card
 * doesn't jump. The shadow still communicates the affordance. */
@media (prefers-reduced-motion:reduce){.fdy-card--interactive:hover{transform:none;}}
/* When the whole card IS the control — a real <button> so the row is keyboard-reachable and
 * announced — reset the UA button box. Note: it does NOT reset background/border, because
 * .fdy-card already sets its own surface + border (resetting them here would strip the card). */
.fdy-card--button{display:block;width:100%;text-align:inherit;color:inherit;appearance:none;-webkit-appearance:none;}
.fdy-card__body{padding:var(--space-5);}
.fdy-card__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-tight);color:var(--color-text);margin:0 0 var(--space-1);}
.fdy-card__desc{font-size:var(--text-sm);color:var(--color-text-muted);margin:0;line-height:var(--leading-normal);}
.fdy-card__footer{padding:var(--space-3) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:linear-gradient(180deg,var(--color-surface),var(--color-surface-2));display:flex;gap:var(--space-2);justify-content:flex-end;}

/* Freeday — Carousel (scroll-snap track + arrows + dots). Enhanced by freeday-carousel.js. */
.fdy-carousel{position:relative;}
.fdy-carousel__viewport{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scroll-behavior:smooth;border-radius:var(--radius-lg);scrollbar-width:none;-ms-overflow-style:none;}
.fdy-carousel__viewport::-webkit-scrollbar{display:none;}
.fdy-carousel__slide{flex:0 0 100%;min-width:0;scroll-snap-align:center;}
.fdy-carousel__arrow{position:absolute;top:50%;transform:translateY(-50%);z-index:2;display:inline-flex;align-items:center;justify-content:center;width:2.25rem;height:2.25rem;border:0;border-radius:var(--radius-full);background:color-mix(in srgb,var(--color-surface) 86%,transparent);color:var(--color-text);box-shadow:var(--shadow-2);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard);}
.fdy-carousel__arrow:hover{background:var(--color-surface);}
.fdy-carousel__arrow:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 40%,transparent);}
.fdy-carousel__arrow:disabled{opacity:.4;cursor:not-allowed;}
.fdy-carousel__arrow--prev{left:var(--space-3);}
.fdy-carousel__arrow--next{right:var(--space-3);}
.fdy-carousel__arrow svg{display:block;width:1.25rem;height:1.25rem;}
.fdy-carousel__dots{display:flex;justify-content:center;gap:var(--space-2);margin-top:var(--space-3);}
.fdy-carousel__dot{width:.5rem;height:.5rem;padding:0;border:0;border-radius:var(--radius-full);background:var(--color-border-strong);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),width var(--dur-fast) var(--ease-standard);}
.fdy-carousel__dot[aria-current="true"]{background:var(--color-primary);width:1.25rem;}
.fdy-carousel__dot:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 40%,transparent);}
@media (prefers-reduced-motion:reduce){.fdy-carousel__viewport{scroll-behavior:auto;}}

/* Freeday — Cascade select (hierarchical drill-down picker).
 * Built by freeday-cascade.js from a [data-fdy-cascade] wrapper whose hidden
 * nested <ul> is the data model: a <li> with a child <ul> is a branch, one
 * without is a selectable leaf. The popover shows one level at a time — branches
 * drill in, a back control ascends, a leaf selects (value = full path).
 * Trigger visual matches the combo / date / time control family. */
.fdy-cascade{position:relative;display:inline-block;width:100%;max-width:22rem;}
.fdy-cascade__trigger{display:inline-flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
.fdy-cascade__trigger:hover{border-color:var(--color-text-muted);}
.fdy-cascade__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-cascade__trigger.is-open{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-cascade__trigger:disabled,.fdy-cascade__trigger[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
.fdy-cascade__trigger[aria-readonly="true"]{background:var(--color-surface-2);border-color:var(--color-border);cursor:default;}
.fdy-cascade__trigger[aria-readonly="true"]:hover{border-color:var(--color-border);}
.fdy-cascade__trigger[aria-readonly="true"]:focus-visible{border-color:var(--color-border-strong);box-shadow:none;}
.fdy-cascade--error .fdy-cascade__trigger,.fdy-cascade__trigger[aria-invalid="true"]{border-color:var(--color-danger);}
.fdy-cascade--error .fdy-cascade__trigger:focus-visible,.fdy-cascade--error .fdy-cascade__trigger.is-open,.fdy-cascade__trigger[aria-invalid="true"]:focus-visible{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
.fdy-cascade__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-cascade__value--placeholder{color:var(--color-text-subtle);}
.fdy-cascade__trigger::after{content:"";flex:none;width:.5rem;height:.5rem;margin-top:-.15rem;border-right:2px solid var(--color-text-subtle);border-bottom:2px solid var(--color-text-subtle);transform:rotate(45deg);transition:transform var(--dur-fast) var(--ease-standard);}
.fdy-cascade__trigger.is-open::after{transform:rotate(225deg);margin-top:.1rem;}

.fdy-cascade__panel{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:130;min-width:100%;margin:0;padding:var(--space-1);background:var(--color-surface);color:var(--color-text);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);}
.fdy-cascade__panel[hidden]{display:none;}
.fdy-cascade__panel:focus-visible{outline:none;}
.fdy-cascade__head{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-1) var(--space-2);margin-bottom:var(--space-1);border-bottom:var(--bw) solid var(--color-border);}
.fdy-cascade__back{display:inline-flex;align-items:center;justify-content:center;flex:none;width:1.5rem;height:1.5rem;padding:0;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);cursor:pointer;}
.fdy-cascade__back:hover{background:var(--color-surface-3);color:var(--color-text);}
.fdy-cascade__back:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
.fdy-cascade__back[hidden]{display:none;}
.fdy-cascade__back svg{display:block;width:1rem;height:1rem;}
.fdy-cascade__crumb{min-width:0;flex:1;font-size:var(--text-xs);font-weight:var(--weight-semibold);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-cascade__list{margin:0;padding:0;list-style:none;max-height:14rem;overflow-y:auto;}
.fdy-cascade__opt{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;white-space:nowrap;}
.fdy-cascade__opt:hover,.fdy-cascade__opt.is-active{background:var(--color-surface-3);}
.fdy-cascade__opt[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
.fdy-cascade__opt-label{overflow:hidden;text-overflow:ellipsis;}
.fdy-cascade__opt-arrow{flex:none;width:.45rem;height:.45rem;border-right:2px solid var(--color-text-subtle);border-bottom:2px solid var(--color-text-subtle);transform:rotate(-45deg);}
@media (prefers-reduced-motion:no-preference){.fdy-cascade__panel:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}

/* Freeday — Choose-from-list dialog (searchable master-data picker).
 * Built on .fdy-modal: header + search + scrollable results table + footer.
 * Backs a choose-from-list field (readonly input + .fdy-input-group__btn magnifier). */
.fdy-modal--cfl{width:min(46rem,calc(100vw - var(--space-8)));}
.fdy-modal--cfl .fdy-modal__body{padding:0;display:flex;flex-direction:column;min-height:0;overflow:hidden;}

/* Search bar — single leading-icon field; Enter/typing filters the results. */
.fdy-cfl__search{flex:none;padding:var(--space-4) var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}

/* Results — dense rows, sticky header, its own scroll region. */
.fdy-cfl__results{overflow:auto;max-height:min(24rem,50vh);}
.fdy-cfl__results .fdy-table th{position:sticky;top:0;z-index:1;}
.fdy-cfl__row{cursor:pointer;}
.fdy-cfl__row:hover{background:var(--color-surface-2);}
.fdy-cfl__row:focus-visible{outline:none;background:var(--color-primary-soft);box-shadow:inset 2px 0 0 var(--color-primary);}
.fdy-cfl__row[aria-selected="true"]{background:var(--color-primary-soft);}
.fdy-cfl__row[aria-selected="true"] td:first-child{font-weight:var(--weight-semibold);}
.fdy-cfl__check{width:1px;white-space:nowrap;}
.fdy-cfl__check input{pointer-events:none;}

/* Empty result state. */
.fdy-cfl__empty{padding:var(--space-8) var(--space-5);text-align:center;color:var(--color-text-muted);font-size:var(--text-sm);}
.fdy-cfl__empty[hidden]{display:none;}

/* Footer — selection count (multi) sits left, actions right. */
.fdy-modal--cfl .fdy-modal__footer{justify-content:space-between;}
.fdy-cfl__count{font-size:var(--text-sm);color:var(--color-text-muted);}
.fdy-cfl__actions{display:flex;gap:var(--space-2);}

/* Freeday — Charts (zero-dependency CSS/SVG, rendered by freeday-chart.js).
 * Colour comes from --fdy-chart (a token, set inline by the renderer from data-fdy-color). */

/* Sparkline / trend line (SVG) */
.fdy-sparkline{display:inline-block;width:8rem;height:2.25rem;vertical-align:middle;color:var(--fdy-chart,var(--color-primary));}
.fdy-sparkline svg{display:block;width:100%;height:100%;}
.fdy-sparkline__area{fill:currentColor;opacity:.14;stroke:none;}
.fdy-sparkline__line{fill:none;stroke:currentColor;stroke-width:2;stroke-linejoin:round;stroke-linecap:round;}
.fdy-sparkline__dot{fill:currentColor;}

/* Bar chart (flex bars) */
.fdy-bars{position:relative;display:flex;align-items:flex-end;gap:var(--space-2);height:9rem;color:var(--fdy-chart,var(--color-primary));}
.fdy-bars__col{flex:1;display:flex;flex-direction:column;align-items:center;min-width:0;height:100%;}
.fdy-bars__track{flex:1;width:100%;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:var(--space-1);min-height:0;}
.fdy-bars__val{font-size:var(--text-xs);font-variant-numeric:tabular-nums;color:var(--color-text-muted);}
.fdy-bars__bar{width:100%;max-width:2.5rem;border-radius:var(--radius-sm) var(--radius-sm) 0 0;background:currentColor;transition:height var(--dur-base) var(--ease-standard),opacity var(--dur-fast) var(--ease-standard);}
.fdy-bars__label{margin-top:var(--space-1);font-size:var(--text-xs);color:var(--color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;}
/* Hover emphasis: dim all bars while the chart is hovered, keep the hovered one lit. */
@media (hover:hover){.fdy-bars:hover .fdy-bars__bar{opacity:.4;}.fdy-bars__col:hover .fdy-bars__bar{opacity:1;}}

/* Interactive tooltip (shared by bar + donut) — Chart.js-style hover readout. */
.fdy-chart__tip{position:absolute;z-index:5;left:0;top:0;pointer-events:none;transform:translate(-50%,calc(-100% - 8px));background:var(--color-inverse-surface);color:var(--color-inverse-text);font-size:var(--text-xs);font-weight:var(--weight-medium);font-variant-numeric:tabular-nums;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);white-space:nowrap;box-shadow:var(--shadow-2);opacity:0;transition:opacity var(--dur-fast) var(--ease-standard);}
.fdy-chart__tip.is-visible{opacity:1;}

/* Donut (conic-gradient ring + legend) */
.fdy-donut{display:inline-flex;align-items:center;gap:var(--space-5);flex-wrap:wrap;}
.fdy-donut__ring{position:relative;width:8rem;height:8rem;border-radius:50%;flex:none;}
.fdy-donut__ring::after{content:"";position:absolute;inset:24%;border-radius:50%;background:var(--color-surface);}
.fdy-donut__center{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;}
.fdy-donut__center b{font-family:var(--font-display);font-size:var(--text-xl);color:var(--color-text);line-height:1;}
.fdy-donut__center span{font-size:var(--text-xs);color:var(--color-text-muted);}
/* Donut hit-layer: transparent SVG sectors over the ring for per-slice hover. */
.fdy-donut__hit{position:absolute;inset:0;z-index:2;width:100%;height:100%;overflow:visible;}
.fdy-donut__seg{fill:transparent;cursor:pointer;transition:fill var(--dur-fast) var(--ease-standard);}
@media (hover:hover){.fdy-donut__seg:hover{fill:rgba(255,255,255,.3);}}
.fdy-chart__legend{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--space-2);}
.fdy-chart__legend li{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);color:var(--color-text);}
.fdy-chart__swatch{width:.75rem;height:.75rem;border-radius:var(--radius-xs);flex:none;}
/* Horizontal legend for cartesian charts (legend sits above the plot). */
.fdy-chart__legend--row{flex-direction:row;flex-wrap:wrap;gap:var(--space-2) var(--space-4);}

/* Cartesian charts (line / area / multi-series & stacked bar) — SVG with themed axes.
 * Axis colour comes from --chart-grid / --chart-tick (both theme-aware); series colours are
 * set inline by the renderer from --chart-1..8, so the whole chart recolours on data-theme. */
.fdy-chart-xy{position:relative;display:flex;flex-direction:column;gap:var(--space-3);width:100%;}
.fdy-chart-xy__plot{width:100%;aspect-ratio:16/9;min-height:8rem;}
.fdy-chart-xy__plot svg{display:block;width:100%;height:100%;overflow:visible;}
.fdy-chart-xy__grid{stroke:var(--chart-grid);stroke-width:1;shape-rendering:crispEdges;}
.fdy-chart-xy__tick{fill:var(--chart-tick);font-family:var(--font-mono);font-size:9px;}
.fdy-chart-xy__xlabel{fill:var(--chart-tick);font-family:var(--font-body);font-size:9px;}
.fdy-chart-xy__line{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke;}
.fdy-chart-xy__area{stroke:none;opacity:.14;}
.fdy-chart-xy__dot{stroke:var(--color-surface);stroke-width:1;}
.fdy-chart-xy__bar{transition:opacity var(--dur-fast) var(--ease-standard);}
.fdy-chart-xy__band{fill:transparent;cursor:pointer;}

/* Freeday — Chip (tag / removable filter) */
.fdy-chip{display:inline-flex;align-items:center;gap:var(--space-2);height:1.75rem;padding:0 var(--space-3);border-radius:var(--radius-full);font-size:var(--text-xs);font-weight:var(--weight-medium);color:var(--color-text);background:var(--color-surface-3);border:var(--bw) solid var(--color-border);}
.fdy-chip--primary{color:var(--color-primary-strong);background:var(--color-primary-soft);border-color:color-mix(in srgb,var(--color-primary) 22%,transparent);}
/* Categorical tone chips — non-semantic category tags / legend swatches, from the general
 * --tone-1..8 palette. Same validated AA formula as .fdy-avatar--tone-* (text >=4.5:1 both themes,
 * gated by test/contrast.test.mjs). */
.fdy-chip--tone-1,.fdy-chip--tone-2,.fdy-chip--tone-3,.fdy-chip--tone-4,.fdy-chip--tone-5,.fdy-chip--tone-6,.fdy-chip--tone-7,.fdy-chip--tone-8{background:color-mix(in srgb,var(--_fdy-chip-tone) 18%,var(--color-surface));color:color-mix(in srgb,var(--_fdy-chip-tone) 50%,var(--color-text));border-color:color-mix(in srgb,var(--_fdy-chip-tone) 30%,var(--color-border));}
.fdy-chip--tone-1{--_fdy-chip-tone:var(--tone-1);}
.fdy-chip--tone-2{--_fdy-chip-tone:var(--tone-2);}
.fdy-chip--tone-3{--_fdy-chip-tone:var(--tone-3);}
.fdy-chip--tone-4{--_fdy-chip-tone:var(--tone-4);}
.fdy-chip--tone-5{--_fdy-chip-tone:var(--tone-5);}
.fdy-chip--tone-6{--_fdy-chip-tone:var(--tone-6);}
.fdy-chip--tone-7{--_fdy-chip-tone:var(--tone-7);}
.fdy-chip--tone-8{--_fdy-chip-tone:var(--tone-8);}
.fdy-chip__remove{display:inline-flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;margin-right:calc(var(--space-1)*-1);border:0;padding:0;border-radius:var(--radius-full);background:transparent;color:currentColor;opacity:.6;cursor:pointer;font-size:var(--text-sm);line-height:1;}
.fdy-chip__remove:hover{opacity:1;background:color-mix(in srgb,currentColor 16%,transparent);}
.fdy-chip__remove:focus-visible{outline:none;opacity:1;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
/* Group wrapper for a row of chips (choice / filter). */
.fdy-chips{display:flex;flex-wrap:wrap;gap:var(--space-2);}
/* Interactive chips: choice (toggle) + filter (toggle with a check when on).
 * Rendered as <button aria-pressed> and enhanced by freeday-chip.js. */
.fdy-chip--choice,.fdy-chip--filter{cursor:pointer;font-family:inherit;background:var(--color-surface);border-color:var(--color-border);transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
.fdy-chip--choice:hover,.fdy-chip--filter:hover{background:var(--color-surface-3);border-color:var(--color-text-subtle);}
.fdy-chip--choice:focus-visible,.fdy-chip--filter:focus-visible{outline:none;box-shadow:0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
.fdy-chip--choice[aria-pressed="true"],.fdy-chip--filter[aria-pressed="true"]{color:var(--color-primary-strong);background:var(--color-primary-soft);border-color:color-mix(in srgb,var(--color-primary) 40%,transparent);}
.fdy-chip--choice:disabled,.fdy-chip--filter:disabled,.fdy-chip--choice[aria-disabled="true"],.fdy-chip--filter[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
.fdy-chip__check{display:none;flex:none;width:.85rem;height:.85rem;margin-left:calc(var(--space-1)*-1);}
.fdy-chip__check svg{display:block;width:100%;height:100%;}
.fdy-chip--filter[aria-pressed="true"] .fdy-chip__check{display:inline-flex;}

/* Freeday — Combobox (custom styled select, WAI-ARIA APG select-only) */
.fdy-combo{position:relative;display:block;max-width:22rem;}
.fdy-combo__button{display:inline-flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
.fdy-combo__button:hover{border-color:var(--color-text-muted);}
.fdy-combo__button:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-combo__button.is-open{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-combo__button:disabled,.fdy-combo__button[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
/* Read-only: stays focusable & shows its value at full contrast but can't open — muted surface,
   softened border, default cursor, no focus-ring escalation (matches input[readonly], #39). */
.fdy-combo__button[aria-readonly="true"]{background:var(--color-surface-2);border-color:var(--color-border);cursor:default;}
.fdy-combo__button[aria-readonly="true"]:hover{border-color:var(--color-border);}
.fdy-combo__button[aria-readonly="true"]:focus-visible{border-color:var(--color-border-strong);box-shadow:none;}
.fdy-combo--error .fdy-combo__button,.fdy-combo__button[aria-invalid="true"]{border-color:var(--color-danger);}
.fdy-combo--error .fdy-combo__button:focus-visible,.fdy-combo--error .fdy-combo__button.is-open,.fdy-combo__button[aria-invalid="true"]:focus-visible{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
.fdy-combo__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-combo__value--placeholder{color:var(--color-text-subtle);}
.fdy-combo__button::after{content:"";flex:none;width:.5rem;height:.5rem;margin-top:-.15rem;border-right:2px solid var(--color-text-subtle);border-bottom:2px solid var(--color-text-subtle);transform:rotate(45deg);transition:transform var(--dur-fast) var(--ease-standard);}
.fdy-combo__button.is-open::after{transform:rotate(225deg);margin-top:.1rem;}
/* Icon variants: --no-icon drops the default caret; add a .fdy-combo__icon element
 * inside the button (with --no-icon) to supply a custom trailing icon. */
.fdy-combo--no-icon .fdy-combo__button::after{display:none;}
.fdy-combo__icon{flex:none;display:inline-flex;color:var(--color-text-subtle);}
.fdy-combo__icon svg{display:block;width:1.05rem;height:1.05rem;}
.fdy-combo__listbox{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:120;min-width:100%;max-height:16rem;overflow-y:auto;margin:0;padding:var(--space-1);list-style:none;background:var(--color-surface);color:var(--color-text);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);}
.fdy-combo__listbox[hidden]{display:none;}
.fdy-combo__option{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;white-space:nowrap;}
.fdy-combo__option.is-highlighted{background:var(--color-surface-3);}
.fdy-combo__option[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
.fdy-combo__option.is-highlighted[aria-selected="true"]{box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-primary) 55%,transparent);}
.fdy-combo__check{display:inline-flex;justify-content:center;width:var(--space-4);flex:none;font-weight:var(--weight-bold);color:var(--color-primary);}
@media (prefers-reduced-motion:no-preference){.fdy-combo__listbox:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}
@keyframes fdy-combo-in{from{opacity:0;transform:translateY(-4px);}to{opacity:1;transform:none;}}

/* Freeday — Page composition & type roles.
 *
 * The kit stops at the component; these primitives encode *how a page is assembled* so screens
 * built by different people cohere. They carry the usage doctrine (see USAGE.md) in markup: a
 * named type role gets used, a doc gets skimmed. Everything here is token-driven layout — no new
 * colours, no new shadows. Pair with .fdy-app (the shell) and the components inside.
 */

/* ---- Type roles (three title levels + supporting text) -------------------------------------
 * One role per level of hierarchy. Reach for these instead of re-using .fdy-card__title for a
 * page title (the mistake that collapses three levels into one grey mush). */
.fdy-eyebrow{font-family:var(--font-body);font-size:var(--text-xs);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-wide);text-transform:uppercase;color:var(--color-text-subtle);}
.fdy-title-page{font-family:var(--font-display);font-size:var(--text-3xl);font-weight:var(--weight-bold);letter-spacing:var(--tracking-tighter);line-height:var(--leading-tight);color:var(--color-text);margin:0;text-wrap:balance;}
.fdy-title-section{font-family:var(--font-display);font-size:var(--text-xl);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-tight);line-height:var(--leading-snug);color:var(--color-text);margin:0;text-wrap:balance;}
.fdy-title-card{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-tight);color:var(--color-text);margin:0;}
.fdy-text-muted{color:var(--color-text-muted);}
.fdy-text-subtle{color:var(--color-text-subtle);}
.fdy-text-caption{font-size:var(--text-sm);color:var(--color-text-muted);margin:0;}

/* ---- Page: the vertical stack of sections, with the section rhythm between them ------------- */
.fdy-page{display:flex;flex-direction:column;gap:var(--space-8);}

/* ---- Page header: eyebrow + title + description on the left, primary action(s) on the right -- */
.fdy-page__header{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4);flex-wrap:wrap;}
.fdy-page__heading{display:flex;flex-direction:column;gap:var(--space-2);min-width:0;}
.fdy-page__desc{font-size:var(--text-base);color:var(--color-text-muted);margin:0;max-width:62ch;line-height:var(--leading-normal);}
.fdy-page__actions{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;}

/* ---- Page section: a heading (+ optional toolbar) and its body, with the intra-group rhythm --- */
.fdy-page-section{display:flex;flex-direction:column;gap:var(--space-4);}
.fdy-page-section__head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-3);flex-wrap:wrap;}

/* ---- Toolbar: a horizontal control row (search + actions), wraps cleanly ---------------------- */
.fdy-toolbar{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;}
.fdy-toolbar__spacer{flex:1;}
.fdy-toolbar__search{max-width:18rem;flex:1 1 12rem;}

/* ---- Stat tile: a KPI metric that is deliberately NOT a card, so a KPI strip doesn't become an
 * identical-white-card grid. Flat by default; wrap the .fdy-stats grid in one card if you want a
 * single boxed strip, or use .fdy-stats--boxed for shared surface + dividers. */
.fdy-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));gap:var(--space-5);}
.fdy-stat{display:flex;flex-direction:column;gap:var(--space-1);min-width:0;}
.fdy-stat__label{font-size:var(--text-xs);font-weight:var(--weight-semibold);letter-spacing:var(--tracking-wide);text-transform:uppercase;color:var(--color-text-subtle);}
.fdy-stat__value{font-family:var(--font-display);font-size:var(--text-3xl);font-weight:var(--weight-bold);letter-spacing:var(--tracking-tighter);line-height:1;color:var(--color-text);font-variant-numeric:tabular-nums;}
.fdy-stat__value small{font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text-muted);}
.fdy-stat__meta{font-size:var(--text-sm);color:var(--color-text-muted);display:flex;align-items:center;gap:var(--space-2);}
.fdy-stats--boxed{background:var(--color-surface);border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-1);gap:0;}
.fdy-stats--boxed .fdy-stat{padding:var(--space-5);border-right:var(--bw) solid var(--color-border-muted);}
.fdy-stats--boxed .fdy-stat:last-child{border-right:0;}

/* Freeday — Date picker (input-styled trigger + calendar popover).
 * Built by freeday-datepicker.js from an empty [data-fdy-datepicker] wrapper. */
.fdy-datepicker{position:relative;display:inline-block;width:100%;max-width:14rem;}
.fdy-datepicker__trigger{display:inline-flex;align-items:center;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
.fdy-datepicker__trigger:hover{border-color:var(--color-text-muted);}
.fdy-datepicker__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-datepicker__trigger.is-open{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-datepicker--error .fdy-datepicker__trigger,.fdy-datepicker__trigger[aria-invalid="true"]{border-color:var(--color-danger);}
.fdy-datepicker--error .fdy-datepicker__trigger:focus-visible,.fdy-datepicker--error .fdy-datepicker__trigger.is-open,.fdy-datepicker__trigger[aria-invalid="true"]:focus-visible{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
.fdy-datepicker__trigger:disabled,.fdy-datepicker__trigger[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
.fdy-datepicker__trigger[aria-readonly="true"]{background:var(--color-surface-2);border-color:var(--color-border);cursor:default;}
.fdy-datepicker__trigger[aria-readonly="true"]:hover{border-color:var(--color-border);}
.fdy-datepicker__trigger[aria-readonly="true"]:focus-visible{border-color:var(--color-border-strong);box-shadow:none;}
.fdy-datepicker__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-datepicker__value--placeholder{color:var(--color-text-subtle);}
.fdy-datepicker__icon{flex:none;display:inline-flex;color:var(--color-text-subtle);}
.fdy-datepicker__icon svg{display:block;width:1.05rem;height:1.05rem;}
/* Clearable: a reset button overlaid in the icon slot (the trigger is itself a <button>, so the
   clear control is a sibling, not a child). Shown only when clearable + a date is set; the calendar
   icon is hidden (kept in flow so the value's ellipsis boundary doesn't shift). */
.fdy-datepicker__icon.is-hidden{visibility:hidden;}
.fdy-datepicker__clear{position:absolute;top:50%;right:var(--space-3);transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:1.15rem;height:1.15rem;padding:0;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-subtle);cursor:pointer;transition:color var(--dur-fast) var(--ease-standard),background var(--dur-fast) var(--ease-standard);}
.fdy-datepicker__clear:hover{color:var(--color-text);background:var(--color-surface-2);}
.fdy-datepicker__clear:focus-visible{outline:none;color:var(--color-text);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-datepicker__clear svg{display:block;width:.9rem;height:.9rem;}

.fdy-datepicker__panel{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:130;padding:var(--space-3);background:var(--color-surface);color:var(--color-text);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);}
.fdy-datepicker__panel[hidden]{display:none;}

/* Calendar grid */
.fdy-cal__head{display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-2);}
.fdy-cal__title{flex:1;text-align:center;font-weight:var(--weight-semibold);font-size:var(--text-sm);color:var(--color-text);text-transform:capitalize;}
.fdy-cal__nav{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;flex:none;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-size:var(--text-lg);line-height:1;cursor:pointer;}
.fdy-cal__nav:hover{background:var(--color-surface-2);color:var(--color-text);}
.fdy-cal__nav:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-cal__grid{display:grid;grid-template-columns:repeat(7,2rem);gap:2px;}
.fdy-cal__dow{display:flex;align-items:center;justify-content:center;height:1.75rem;font-size:var(--text-xs);font-weight:var(--weight-semibold);color:var(--color-text-muted);text-transform:capitalize;}
.fdy-cal__day{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-size:var(--text-sm);font-variant-numeric:tabular-nums;cursor:pointer;}
.fdy-cal__day:hover{background:var(--color-surface-2);}
.fdy-cal__day:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-cal__day.is-outside{color:var(--color-text-subtle);opacity:.55;}
.fdy-cal__day.is-today{font-weight:var(--weight-bold);box-shadow:inset 0 0 0 1.5px var(--color-border-strong);}
.fdy-cal__day.in-range{background:var(--color-primary-soft);color:var(--color-primary-strong);border-radius:0;}
.fdy-cal__day.is-selected{background:var(--color-primary);color:var(--color-on-primary);font-weight:var(--weight-semibold);}
.fdy-cal__day.is-selected:hover{background:var(--color-primary-hover);}
.fdy-cal__day:disabled{opacity:.35;cursor:not-allowed;}
.fdy-cal__day:disabled:hover{background:transparent;}

/* Range: two linked pickers */
/* Responsive: each picker may shrink (min-width:0) & wrap so the range never overflows a
   narrow row/phone; inline-flex still hugs to ~23rem at wider widths (look unchanged). */
.fdy-daterange{display:inline-flex;flex-wrap:wrap;align-items:center;gap:var(--space-2);}
/* Each picker shrinks from an 11rem basis but not below ~7rem — enough for "dd/mm/yyyy" + the icon,
   so a squeezed range compresses gracefully (and wraps) instead of clipping the date. */
.fdy-daterange .fdy-datepicker{flex:0 1 11rem;min-width:7rem;}
.fdy-daterange__sep{flex:none;color:var(--color-text-subtle);}

@media (prefers-reduced-motion:no-preference){.fdy-datepicker__panel:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}

/* Freeday — Datetime picker (composed: date picker + time picker → one value).
 * A thin composer (freeday-datetime.js) links a child [data-fdy-datepicker] and
 * [data-fdy-timepicker] and emits a single combined event. Icon variants come from
 * the child pickers (data-fdy-no-icon / <template data-fdy-icon>). */
.fdy-datetimepicker{display:inline-flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;}
/* Fixed widths so date + time sit side by side (children default to width:100%). */
.fdy-datetimepicker .fdy-datepicker{width:12rem;max-width:none;}
.fdy-datetimepicker .fdy-timepicker{width:8.5rem;max-width:none;}

/* Freeday — Description list (key-value detail view) */
.fdy-dl{display:grid;grid-template-columns:auto 1fr;gap:var(--space-2) var(--space-5);margin:0;}
.fdy-dl dt{color:var(--color-text-muted);font-size:var(--text-sm);}
.fdy-dl dd{margin:0;color:var(--color-text);font-size:var(--text-sm);font-weight:var(--weight-medium);}
.fdy-dl--rows{grid-template-columns:1fr;gap:var(--space-1);}
.fdy-dl--rows dt{margin-top:var(--space-2);}

/* Freeday — Divider */
.fdy-divider{border:0;border-top:var(--bw) solid var(--color-border);margin:var(--space-4) 0;}
.fdy-divider--vertical{border-top:0;border-left:var(--bw) solid var(--color-border);margin:0 var(--space-4);align-self:stretch;}

/* Freeday — Drawer (temporary side panel on native <dialog>: focus-trap / Esc /
 * backdrop / return-focus are free). Anchors left (default) or right.
 * Enhanced by freeday-drawer.js (open trigger + backdrop-click close). */
/* display is gated behind [open] so the native <dialog> stays hidden until opened.
 * An unconditional display here would beat the UA `dialog:not([open]){display:none}`
 * rule (author origin wins over user-agent) and leave the drawer visible on load. */
.fdy-drawer{position:fixed;inset:0 auto 0 0;margin:0;padding:0;height:100vh;max-height:none;width:min(20rem,82vw);flex-direction:column;border:0;background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-4);overflow:hidden;transform:translateX(-100%);transition:transform var(--dur-slow) var(--ease-standard),overlay var(--dur-slow) allow-discrete,display var(--dur-slow) allow-discrete;}
.fdy-drawer[open]{display:flex;transform:none;}
.fdy-drawer--right{inset:0 0 0 auto;transform:translateX(100%);}
.fdy-drawer::backdrop{background:rgba(10,12,25,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--dur-slow) var(--ease-standard),overlay var(--dur-slow) allow-discrete,display var(--dur-slow) allow-discrete;}
.fdy-drawer__header{flex:none;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4) var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
.fdy-drawer__title{font-family:var(--font-display);font-weight:var(--weight-semibold);font-size:var(--text-lg);color:var(--color-text);margin:0 auto 0 0;}
.fdy-drawer__close{border:0;background:transparent;color:var(--color-text-muted);font-size:var(--text-xl);line-height:1;cursor:pointer;padding:var(--space-1);border-radius:var(--radius-sm);}
.fdy-drawer__close:hover{background:var(--color-surface-2);color:var(--color-text);}
.fdy-drawer__body{flex:1;min-height:0;overflow:auto;padding:var(--space-4);}
.fdy-drawer__footer{flex:none;display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
/* Symmetric enter AND exit on the native <dialog>: @starting-style animates the entry;
 * the overlay/display allow-discrete transitions keep the panel painted through the exit so
 * it slides back out on close (not just in). prefers-reduced-motion is honored by the global
 * duration reset in base.css. Unsupported browsers degrade to an instant open/close. */
.fdy-drawer[open]::backdrop{opacity:1;}
@starting-style{
  .fdy-drawer[open]{transform:translateX(-100%);}
  .fdy-drawer--right[open]{transform:translateX(100%);}
  .fdy-drawer[open]::backdrop{opacity:0;}
}

/* Freeday — File upload (drop target + explicit per-file states).
 * Enhanced by freeday-upload.js; states: idle · drag-over · uploading · done · error. */
.fdy-dropzone{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);padding:var(--space-6);text-align:center;border:2px dashed var(--color-control-border);border-radius:var(--radius-lg);background:var(--color-surface-2);color:var(--color-text-muted);cursor:pointer;transition:border-color var(--dur-fast) var(--ease-standard),background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
.fdy-dropzone:hover{border-color:var(--color-text-muted);}
.fdy-dropzone:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-dropzone.is-dragover{border-color:var(--color-primary);background:var(--color-primary-soft);color:var(--color-primary-strong);}
.fdy-dropzone[aria-disabled="true"],.fdy-dropzone.is-disabled{opacity:.55;cursor:not-allowed;pointer-events:none;}
.fdy-dropzone__icon{color:var(--color-text-subtle);}
.fdy-dropzone.is-dragover .fdy-dropzone__icon{color:var(--color-primary);}
.fdy-dropzone__icon svg{display:block;width:2rem;height:2rem;}
.fdy-dropzone__title{font-weight:var(--weight-medium);color:var(--color-text);}
.fdy-dropzone__hint{font-size:var(--text-xs);}
/* Wide (horizontal) layout — icon beside the copy instead of stacked, for full-width
 * sections. Wrap the title + hint in .fdy-dropzone__text. */
.fdy-dropzone--row{flex-direction:row;align-items:center;justify-content:center;text-align:left;gap:var(--space-4);}
.fdy-dropzone__text{display:flex;flex-direction:column;gap:var(--space-1);}

/* File rows (list of added/uploaded/rejected files) */
.fdy-filelist{display:flex;flex-direction:column;gap:var(--space-2);margin-top:var(--space-3);}
/* Side-by-side rows on wide screens (reflow to one column when narrow). */
.fdy-filelist--grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(16rem,1fr));}
.fdy-file{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3);border:var(--bw) solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);}
.fdy-file__icon{flex:none;display:inline-flex;color:var(--color-text-muted);}
.fdy-file__icon svg{display:block;width:1.25rem;height:1.25rem;}
.fdy-file__meta{flex:1;min-width:0;}
.fdy-file__name{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fdy-file__sub{font-size:var(--text-xs);color:var(--color-text-muted);}
.fdy-file__progress{margin-top:var(--space-2);}
.fdy-file__remove{flex:none;display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-size:var(--text-lg);line-height:1;cursor:pointer;}
.fdy-file__remove:hover{background:var(--color-surface-2);color:var(--color-text);}
.fdy-file__remove:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-file--success .fdy-file__icon{color:var(--color-success);}
.fdy-file--error{border-color:color-mix(in srgb,var(--color-danger) 40%,var(--color-border));}
.fdy-file--error .fdy-file__icon{color:var(--color-danger);}
.fdy-file--error .fdy-file__sub{color:var(--color-danger-strong);}

/* Freeday — Filter bar (a consistent row of filters: search + selects + actions).
 * Solves the "ragged filter row": apps improvised flex rows with ad-hoc
 * flex/min-width, so grow fields ballooned while selects stayed tiny and no two
 * screens matched. Here every field snaps to a shared width rhythm; one field may
 * --w-grow to absorb the slack; trailing actions align to the controls. Fields are
 * the standard .fdy-field (label above control); wraps gracefully on narrow screens. */
.fdy-filterbar{display:flex;flex-wrap:wrap;align-items:flex-end;gap:var(--space-3) var(--space-4);}
/* Composed with a table toolbar (one element, both classes): the fields decide the alignment.
 * `.fdy-table-toolbar` sets align-items:center (right for bare buttons) at equal specificity, and
 * being later in the bundle it would otherwise win — floating labelled fields' neighbours out of line.
 * This 2-class selector (0,2,0) settles it toward the filterbar's flex-end regardless of source order. */
.fdy-table-toolbar.fdy-filterbar{align-items:flex-end;}
/* Fields are direct children. Drop the standalone field's 22rem cap; default to the
 * medium column width with no unbounded growth (that's what caused the raggedness). */
.fdy-filterbar>.fdy-field{max-width:none;flex:0 0 auto;width:12rem;}
/* Controls fill their field's column (drop the standalone input-group/combo caps). */
.fdy-filterbar>.fdy-field .fdy-input-group,.fdy-filterbar>.fdy-field .fdy-combo{max-width:none;width:100%;}
/* Column-width rhythm — pick one per field so bars across the app line up. */
.fdy-filterbar>.fdy-field--w-sm{width:9rem;}
.fdy-filterbar>.fdy-field--w-lg{width:15rem;}
.fdy-filterbar>.fdy-field--w-xl{width:18rem;}
/* Wide enough for a two-picker date range (~25rem) so it need not burn the single --w-grow slot. */
.fdy-filterbar>.fdy-field--w-2xl{width:25rem;}
/* One growing field (usually the search) absorbs the remaining width. */
.fdy-filterbar>.fdy-field--w-grow{flex:1 1 16rem;width:auto;min-width:12rem;}
/* Trailing actions (buttons) pushed to the end, aligned with the controls' baseline.
 * Wrap note: a wrapped bar breaks flex lines on each item's *flex-basis* (the grow field's
 * `flex:1 1 16rem` reserves 16rem for line-breaking), NOT its rendered width — so the grow basis,
 * not the visible width, decides the wrap point. Margins can't keep the actions off a lonely wrapped
 * row; to avoid stranded actions, tune the --w-grow basis or drop a field so the bar fits one row. */
.fdy-filterbar__actions{display:flex;align-items:center;gap:var(--space-2);margin-left:auto;}
/* Opt-in: sit the actions inline right after the last field instead of at the far edge — so when the
 * bar wraps they read as attached to the filters rather than shoved to the right of a lonely row. */
.fdy-filterbar--actions-inline .fdy-filterbar__actions{margin-left:0;}
/* Stack on narrow screens so nothing overflows the row. */
@media (max-width:640px){
  .fdy-filterbar>.fdy-field,.fdy-filterbar>.fdy-field--w-sm,.fdy-filterbar>.fdy-field--w-lg,.fdy-filterbar>.fdy-field--w-xl,.fdy-filterbar>.fdy-field--w-2xl,.fdy-filterbar>.fdy-field--w-grow{width:100%;flex:1 1 100%;}
  .fdy-filterbar__actions{width:100%;margin-left:0;}
}

/* Freeday — Form grid (document/header fields laid out in aligned columns).
 * The two-dimensional counterpart to the single-column .fdy-field stack and the
 * one-row .fdy-filterbar: related fields sit in columns that reflow to one on narrow
 * screens. Fields are the standard .fdy-field; a field with --full spans the whole row
 * (e.g. an address or note). Zero JS — pure layout over .fdy-field. */
.fdy-form-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:var(--space-4) var(--space-5);}
.fdy-form-grid>.fdy-field{max-width:none;}
.fdy-form-grid>.fdy-field--full{grid-column:1/-1;}

/* Freeday — Input group (prefix/suffix addons, e.g. Rp / % / icon) */
.fdy-input-group{display:flex;align-items:stretch;max-width:22rem;background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);overflow:hidden;transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
.fdy-input-group:hover{border-color:var(--color-text-muted);}
.fdy-input-group:focus-within{border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-input-group .fdy-input{flex:1;min-width:0;border:0;background:transparent;box-shadow:none;border-radius:0;height:calc(var(--control-h) - 3px);}
.fdy-input-group .fdy-input:focus{box-shadow:none;}
.fdy-input-group__addon{display:inline-flex;align-items:center;padding:0 var(--space-3);background:var(--color-surface-2);color:var(--color-text-muted);font-size:var(--text-sm);white-space:nowrap;border-right:var(--bw) solid var(--color-border);}
.fdy-input-group__addon:last-child{border-right:0;border-left:var(--bw) solid var(--color-border);}
/* Borderless leading icon (e.g. search magnifier) — self-contained like __btn so it
   centers standalone (no base .fdy-input-group__addon required). */
.fdy-input-group__addon--icon{display:inline-flex;align-items:center;background:transparent;border:0;padding:0 0 0 var(--space-3);color:var(--color-text-subtle);}
.fdy-input-group__addon--icon svg{display:block;width:1rem;height:1rem;}
/* The leading icon already provides the left inset — don't let the input add its full left padding on top. */
.fdy-input-group__addon--icon + .fdy-input{padding-left:var(--space-2);}
/* Trailing action button (e.g. choose-from-list magnifier) — a real, focusable control. */
.fdy-input-group__btn{display:inline-flex;align-items:center;justify-content:center;flex:none;width:var(--control-h);align-self:stretch;border:0;border-left:var(--bw) solid var(--color-border);background:var(--color-surface-2);color:var(--color-text-muted);cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),color var(--dur-fast) var(--ease-standard);}
.fdy-input-group__btn:hover{background:var(--color-surface-3);color:var(--color-text);}
.fdy-input-group__btn:focus-visible{outline:none;color:var(--color-text);box-shadow:inset 0 0 0 2px var(--color-primary);}
.fdy-input-group__btn svg{display:block;width:1.1rem;height:1.1rem;}
/* Error state must win over the neutralizing rules above — promote to the wrapper. */
.fdy-input-group:has(.fdy-input--error),.fdy-input-group:has(.fdy-combo--error),.fdy-input-group:has([aria-invalid="true"]){border-color:var(--color-danger);}
.fdy-input-group:has(.fdy-input--error):focus-within,.fdy-input-group:has(.fdy-combo--error):focus-within,.fdy-input-group:has([aria-invalid="true"]):focus-within{border-color:var(--color-danger);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}

/* Freeday — Field & Input */
.fdy-field{display:flex;flex-direction:column;gap:var(--space-2);max-width:22rem;}
/* A grouped field is legitimately a <fieldset> (it needs a <legend>) — e.g. a radio/checkbox group.
   Neutralise the UA groove border / padding / min-inline-size so it lays out identically to the
   <div> form (min-inline-size:min-content would otherwise block the filterbar column widths). */
fieldset.fdy-field{border:0;margin:0;padding:0;min-inline-size:0;}
fieldset.fdy-field>legend{padding:0;float:none;}
.fdy-label{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);}
.fdy-input,.fdy-textarea{width:100%;height:var(--control-h);padding:0 var(--space-3);font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
.fdy-input::placeholder,.fdy-textarea::placeholder{color:var(--color-text-subtle);}
.fdy-textarea{height:auto;min-height:5.5rem;padding:var(--space-3);line-height:var(--leading-normal);resize:vertical;}
.fdy-input:hover,.fdy-textarea:hover{border-color:var(--color-text-muted);}
.fdy-input:focus,.fdy-textarea:focus{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-input:disabled,.fdy-textarea:disabled,.fdy-input[aria-disabled="true"],.fdy-textarea[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
/* Read-only (#39): the value is real and may be read/copied, only not edited. Full contrast (unlike
   :disabled which dims to placeholder-grey), muted surface + softened border so it still reads as
   inert, default cursor, no focus-ring escalation. */
.fdy-input[readonly],.fdy-textarea[readonly]{background:var(--color-surface-2);border-color:var(--color-border);color:var(--color-text);cursor:default;}
.fdy-input[readonly]:hover,.fdy-textarea[readonly]:hover{border-color:var(--color-border);}
.fdy-input[readonly]:focus-visible,.fdy-textarea[readonly]:focus-visible{border-color:var(--color-border-strong);box-shadow:none;}
.fdy-input--error,.fdy-input[aria-invalid="true"],.fdy-textarea[aria-invalid="true"]{border-color:var(--color-danger);}
.fdy-input--error:focus,.fdy-input[aria-invalid="true"]:focus,.fdy-textarea[aria-invalid="true"]:focus{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
.fdy-help{font-size:var(--text-xs);color:var(--color-text-muted);}
.fdy-help--error{color:var(--color-danger);}

/* Freeday — Keyboard key */
.fdy-kbd{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;height:1.5rem;padding:0 var(--space-2);font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text);background:var(--color-surface-2);border:var(--bw) solid var(--color-border-strong);border-bottom-width:2px;border-radius:var(--radius-sm);}

/* Freeday — Menu (action popup) + Split button. Enhanced by freeday-menu.js. */
.fdy-menu-wrap{position:relative;display:inline-flex;}
.fdy-menu{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:130;min-width:11rem;margin:0;padding:var(--space-1);list-style:none;background:var(--color-surface);color:var(--color-text);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);}
.fdy-menu[hidden]{display:none;}
.fdy-menu--end{left:auto;right:0;}
.fdy-menu__item{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:var(--space-2) var(--space-3);border:0;background:transparent;border-radius:var(--radius-sm);font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);text-align:left;cursor:pointer;white-space:nowrap;}
.fdy-menu__item:hover,.fdy-menu__item.is-highlighted{background:var(--color-surface-3);}
.fdy-menu__item:focus-visible{outline:none;background:var(--color-surface-3);}
.fdy-menu__item:disabled{opacity:.5;cursor:not-allowed;background:transparent;}
.fdy-menu__item--danger{color:var(--color-danger-strong);}
.fdy-menu__item svg{display:block;width:1rem;height:1rem;flex:none;}
.fdy-menu__sep{height:0;margin:var(--space-1) 0;border:0;border-top:var(--bw) solid var(--color-border-muted);}
@media (prefers-reduced-motion:no-preference){.fdy-menu:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}

/* Split button — main action + attached menu toggle (caret) */
.fdy-btn-split{position:relative;display:inline-flex;border-radius:var(--radius-md);transition:transform var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
/* One control: the two halves must stay coplanar. Neutralize each segment's own
   lift + drop-shadow (they would misalign the seam / glow a single half); the
   split lifts and casts its elevation as a single unit instead. */
.fdy-btn-split > .fdy-btn{transform:none;box-shadow:inset 0 1px 0 rgba(255,255,255,.26);}
.fdy-btn-split > .fdy-btn:first-child{border-top-right-radius:0;border-bottom-right-radius:0;}
.fdy-btn-split__toggle{padding:0 var(--space-2);margin-left:calc(var(--bw) * -1);border-top-left-radius:0;border-bottom-left-radius:0;}
/* Hairline divider between the halves (outranks the segment rule above). */
.fdy-btn-split > .fdy-btn-split__toggle{box-shadow:inset 0 1px 0 rgba(255,255,255,.26),inset 1px 0 0 rgba(0,0,0,.16);}
.fdy-btn-split:hover{transform:translateY(-1px);box-shadow:0 6px 18px -2px color-mix(in srgb,var(--color-primary) 55%,transparent);}
.fdy-btn-split:active{transform:translateY(1px);box-shadow:0 1px 4px -1px color-mix(in srgb,var(--color-primary) 46%,transparent);}
.fdy-btn-split__toggle:hover,.fdy-btn-split__toggle:focus-visible{z-index:1;}
.fdy-btn-split__toggle svg{display:block;width:1rem;height:1rem;}

/* Freeday — Modal (native <dialog>) */
.fdy-modal{width:min(32rem,calc(100vw - var(--space-8)));max-height:calc(100vh - var(--space-16));padding:0;border:var(--bw) solid var(--color-border);border-radius:var(--radius-xl);background:var(--color-surface);color:var(--color-text);box-shadow:var(--shadow-lift-hover);overflow:hidden;flex-direction:column;opacity:0;transform:translateY(8px) scale(.98);transition:opacity var(--dur-base) var(--ease-spring),transform var(--dur-base) var(--ease-spring),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
.fdy-modal--sm{width:min(24rem,calc(100vw - var(--space-8)));}
.fdy-modal--md{width:min(32rem,calc(100vw - var(--space-8)));}
.fdy-modal--lg{width:min(48rem,calc(100vw - var(--space-8)));}
.fdy-modal--wide{width:min(60rem,calc(100vw - var(--space-8)));}
.fdy-modal::backdrop{background:rgba(10,12,25,.5);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);opacity:0;transition:opacity var(--dur-base) var(--ease-standard),overlay var(--dur-base) allow-discrete,display var(--dur-base) allow-discrete;}
.fdy-modal__header{flex:none;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-5);border-bottom:var(--bw) solid var(--color-border-muted);}
.fdy-modal__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);margin:0 auto 0 0;}
.fdy-modal__close{border:0;background:transparent;color:var(--color-text-muted);font-size:var(--text-xl);line-height:1;cursor:pointer;padding:var(--space-1);border-radius:var(--radius-sm);}
.fdy-modal__close:hover{background:var(--color-surface-2);color:var(--color-text);}
.fdy-modal__body{flex:1;min-height:0;padding:var(--space-5);overflow:auto;}
.fdy-modal__footer{flex:none;display:flex;gap:var(--space-2);justify-content:flex-end;padding:var(--space-4) var(--space-5);border-top:var(--bw) solid var(--color-border-muted);background:var(--color-surface-2);}
/* Symmetric enter AND exit (fade + rise + subtle scale) on the native <dialog>. @starting-style
 * animates the entry; overlay/display allow-discrete keep it painted through the exit so it
 * animates out on close too. Reduced motion honored by the global duration reset in base.css. */
.fdy-modal[open]{display:flex;opacity:1;transform:none;}
.fdy-modal[open]::backdrop{opacity:1;}
@starting-style{
  .fdy-modal[open]{opacity:0;transform:translateY(8px) scale(.98);}
  .fdy-modal[open]::backdrop{opacity:0;}
}

/* Freeday — Pagination */
.fdy-pagination__list{display:flex;align-items:center;gap:var(--space-1);list-style:none;margin:0;padding:0;}
.fdy-pagination__link{display:inline-flex;align-items:center;justify-content:center;min-width:2.25rem;height:2.25rem;padding:0 var(--space-2);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);background:transparent;border:var(--bw) solid transparent;text-decoration:none;cursor:pointer;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);}
.fdy-pagination__link:hover{background:var(--color-surface-2);border-color:var(--color-border);}
.fdy-pagination__link:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-pagination__link[aria-current="page"]{background:var(--color-primary);color:var(--color-on-primary);}
.fdy-pagination__link[aria-disabled="true"],.fdy-pagination__link:disabled{opacity:.5;cursor:not-allowed;pointer-events:none;}
.fdy-pagination__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2.25rem;height:2.25rem;color:var(--color-text-subtle);}

/* Freeday — Progress */
.fdy-progress{height:.5rem;border-radius:var(--radius-full);background:var(--color-surface-3);overflow:hidden;}
.fdy-progress__bar{height:100%;border-radius:inherit;background:var(--color-primary);transition:width var(--dur-base) var(--ease-standard);}
.fdy-progress--indeterminate{position:relative;}
.fdy-progress--indeterminate .fdy-progress__bar{width:40%;animation:fdy-progress-indet 1.2s var(--ease-standard) infinite;}
@keyframes fdy-progress-indet{0%{margin-left:-40%;}100%{margin-left:100%;}}
@media (prefers-reduced-motion:reduce){.fdy-progress--indeterminate .fdy-progress__bar{animation:none;width:100%;opacity:.5;}}

/* Freeday — Rating (star rating). Interactive = native radio group (arrow keys, form-assoc);
 * filled vs empty differ by fill-vs-outline (not colour alone). Enhanced by freeday-rating.js. */
.fdy-rating{display:inline-flex;gap:var(--space-1);}
.fdy-rating__star{display:inline-flex;line-height:0;cursor:pointer;}
.fdy-rating__star input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;}
.fdy-rating__star svg{width:1.5rem;height:1.5rem;fill:none;stroke:var(--color-border-strong);stroke-width:1.5;transition:fill var(--dur-fast) var(--ease-standard),stroke var(--dur-fast) var(--ease-standard);}
.fdy-rating__star.is-filled svg{fill:var(--color-warning);stroke:var(--color-warning);}
.fdy-rating__star input:focus-visible + svg{outline:2px solid var(--color-primary);outline-offset:2px;border-radius:var(--radius-xs);}
.fdy-rating--readonly .fdy-rating__star{cursor:default;}
/* Disabled: not editable and greyed (readonly stays full-strength; disabled dims). */
.fdy-rating--disabled .fdy-rating__star{cursor:not-allowed;}
.fdy-rating--disabled .fdy-rating__star svg{opacity:.5;}
/* Invalid: tint the (outline) empty stars danger so a required-but-empty rating reads as an error,
   paired with a help/error message — never colour alone. */
.fdy-rating--error .fdy-rating__star svg{stroke:var(--color-danger);}
.fdy-rating--sm .fdy-rating__star svg{width:1.1rem;height:1.1rem;}

/* Freeday — Selection controls */
.fdy-check,.fdy-radio,.fdy-switch{display:inline-flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;}
.fdy-check input,.fdy-radio input{appearance:none;-webkit-appearance:none;width:var(--control-box);height:var(--control-box);margin:0;border:1.5px solid var(--color-control-border);background:var(--color-surface);box-shadow:inset 0 1px 2px var(--color-shadow-inset);cursor:pointer;display:grid;place-content:center;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);}
.fdy-check input{border-radius:var(--radius-sm);}
.fdy-radio input{border-radius:50%;}
.fdy-check input::before{content:"";width:.62rem;height:.62rem;transform:scale(0);transition:transform var(--dur-fast) var(--ease-spring);box-shadow:inset 1rem 1rem var(--color-on-primary);clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0,43% 62%);}
.fdy-radio input::before{content:"";width:.55rem;height:.55rem;border-radius:50%;transform:scale(0);transition:transform var(--dur-fast) var(--ease-spring);box-shadow:inset 1rem 1rem var(--color-on-primary);}
.fdy-check input:checked,.fdy-radio input:checked{background:var(--color-primary);border-color:var(--color-primary);}
.fdy-check input:checked::before,.fdy-radio input:checked::before{transform:scale(1);}
.fdy-check input:focus-visible,.fdy-radio input:focus-visible,.fdy-switch input:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-check input:disabled,.fdy-radio input:disabled,.fdy-switch input:disabled{opacity:.5;cursor:not-allowed;}
.fdy-check:has(input:disabled),.fdy-radio:has(input:disabled),.fdy-switch:has(input:disabled){cursor:not-allowed;}
.fdy-switch input{appearance:none;-webkit-appearance:none;position:relative;width:var(--control-switch-w);height:var(--control-switch-h);margin:0;border-radius:var(--radius-full);background:var(--color-control-border);cursor:pointer;transition:background var(--dur-base) var(--ease-standard);}
.fdy-switch input::before{content:"";position:absolute;top:2px;left:2px;width:calc(var(--control-switch-h) - 4px);height:calc(var(--control-switch-h) - 4px);border-radius:50%;background:var(--color-switch-thumb);box-shadow:var(--shadow-1);transition:transform var(--dur-base) var(--ease-spring);}
.fdy-switch input:checked{background:var(--color-primary);}
.fdy-switch input:checked::before{transform:translateX(calc(var(--control-switch-w) - var(--control-switch-h)));}

/* Standalone checkbox (e.g. table row/select-all) — supports :indeterminate */
.fdy-checkbox{appearance:none;-webkit-appearance:none;width:var(--control-box);height:var(--control-box);margin:0;border:1.5px solid var(--color-control-border);border-radius:var(--radius-sm);background:var(--color-surface);box-shadow:inset 0 1px 2px var(--color-shadow-inset);cursor:pointer;display:grid;place-content:center;transition:background var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);}
.fdy-checkbox::before{content:"";width:.62rem;height:.62rem;transform:scale(0);transition:transform var(--dur-fast) var(--ease-spring);box-shadow:inset 1rem 1rem var(--color-on-primary);clip-path:polygon(14% 44%,0 65%,50% 100%,100% 16%,80% 0,43% 62%);}
.fdy-checkbox:checked,.fdy-checkbox:indeterminate{background:var(--color-primary);border-color:var(--color-primary);}
.fdy-checkbox:checked::before{transform:scale(1);}
.fdy-checkbox:indeterminate::before{width:.6rem;height:2px;transform:scale(1);clip-path:none;box-shadow:none;background:var(--color-on-primary);}
.fdy-checkbox:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-checkbox:disabled{opacity:.5;cursor:not-allowed;}

/* Freeday — Skeleton */
.fdy-skeleton{display:block;border-radius:var(--radius-sm);background:var(--color-surface-3);background-image:linear-gradient(90deg,transparent,color-mix(in srgb,var(--color-surface) 60%,transparent),transparent);background-size:200% 100%;background-repeat:no-repeat;animation:fdy-skeleton 1.4s ease-in-out infinite;}
.fdy-skeleton--text{height:.8rem;margin:.3rem 0;}
.fdy-skeleton--title{height:1.2rem;width:40%;}
.fdy-skeleton--circle{border-radius:var(--radius-full);}
/* Size-matched to .fdy-avatar (2.5rem) and its --sm/--lg, so a skeleton reserves the exact avatar
 * box and data landing causes no layout shift (a plain --circle has no dimensions of its own). */
.fdy-skeleton--avatar{width:2.5rem;height:2.5rem;border-radius:var(--radius-full);}
.fdy-skeleton--avatar-sm{width:2rem;height:2rem;border-radius:var(--radius-full);}
.fdy-skeleton--avatar-lg{width:3.5rem;height:3.5rem;border-radius:var(--radius-full);}
@keyframes fdy-skeleton{to{background-position:-200% 0;}}
@media (prefers-reduced-motion:reduce){.fdy-skeleton{animation:none;}}

/* Freeday — Slider (native <input type="range"> themed via accent-color: keeps native
 * keyboard + ARIA, filled track and thumb come free). Optional value output + scale.
 * freeday-slider.js just mirrors the value into an <output for="…">. */
.fdy-slider{width:100%;max-width:22rem;height:1.5rem;accent-color:var(--color-primary);cursor:pointer;}
.fdy-slider:disabled{cursor:not-allowed;opacity:.6;}
.fdy-slider--accent{accent-color:var(--color-accent);}
.fdy-slider--danger{accent-color:var(--color-danger);}

.fdy-slider-field{display:flex;flex-direction:column;gap:var(--space-2);max-width:22rem;}
.fdy-slider-field__head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-3);}
.fdy-slider__value{font-family:var(--font-mono);font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--color-primary-strong);font-variant-numeric:tabular-nums;}
.fdy-slider__scale{display:flex;justify-content:space-between;font-size:var(--text-xs);color:var(--color-text-muted);font-variant-numeric:tabular-nums;}

/* Freeday — Spinner */
.fdy-spinner{display:inline-block;width:1.5rem;height:1.5rem;border:2.5px solid var(--color-border-strong);border-top-color:var(--color-primary);border-radius:var(--radius-full);animation:fdy-spin .7s linear infinite;}
.fdy-spinner--sm{width:1rem;height:1rem;border-width:2px;}
.fdy-spinner--lg{width:2.5rem;height:2.5rem;border-width:3px;}
@keyframes fdy-spin{to{transform:rotate(360deg);}}
@media (prefers-reduced-motion:reduce){.fdy-spinner{animation-duration:2s;}}

/* Freeday — States (empty / loading / error placeholders) */
.fdy-state{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-2);padding:var(--space-10) var(--space-6);}
.fdy-state__icon{display:inline-flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;color:var(--color-text-subtle);}
.fdy-state__icon svg{width:100%;height:100%;}
.fdy-state__title{font-family:var(--font-display);font-size:var(--text-lg);font-weight:var(--weight-semibold);color:var(--color-text);}
.fdy-state__text{font-size:var(--text-sm);color:var(--color-text-muted);max-width:24rem;line-height:var(--leading-normal);}
.fdy-state__actions{margin-top:var(--space-2);display:flex;gap:var(--space-2);flex-wrap:wrap;justify-content:center;}
.fdy-state--danger .fdy-state__icon{color:var(--color-danger-strong);}

/* Freeday — Stepper / Wizard (progress header + optional panels).
 * Enhanced by freeday-stepper.js for prev/next navigation. */
.fdy-stepper{display:flex;list-style:none;margin:0;padding:0;}
.fdy-step{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;text-align:center;min-width:0;}
/* connector from the previous marker's centre to this one (behind the markers) */
.fdy-step:not(:first-child)::before{content:"";position:absolute;top:.875rem;left:-50%;width:100%;height:2px;transform:translateY(-50%);background:var(--color-border-strong);z-index:0;}
.fdy-step.is-active::before,.fdy-step.is-complete::before{background:var(--color-primary);}
.fdy-step__btn{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:var(--space-2);padding:0 var(--space-2);background:none;border:0;font:inherit;color:inherit;cursor:pointer;max-width:100%;}
.fdy-step__btn:disabled{cursor:default;}
.fdy-step__marker{display:inline-flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;flex:none;border-radius:var(--radius-full);background:var(--color-surface);border:2px solid var(--color-border-strong);color:var(--color-text-muted);font-size:var(--text-sm);font-weight:var(--weight-semibold);font-variant-numeric:tabular-nums;}
.fdy-step__marker svg{display:block;width:1rem;height:1rem;}
.fdy-step.is-active .fdy-step__marker{border-color:var(--color-primary);background:var(--color-primary-soft);color:var(--color-primary-strong);}
.fdy-step.is-complete .fdy-step__marker{border-color:var(--color-primary);background:var(--color-primary);color:var(--color-on-primary);}
.fdy-step.is-error .fdy-step__marker{border-color:var(--color-danger);background:var(--color-danger-btn);color:var(--color-on-danger);}
.fdy-step__label{font-size:var(--text-sm);color:var(--color-text-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;}
.fdy-step.is-active .fdy-step__label{color:var(--color-text);font-weight:var(--weight-semibold);}
.fdy-step__btn:focus-visible{outline:none;}
.fdy-step__btn:focus-visible .fdy-step__marker{box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 30%,transparent);}

.fdy-step-panels{margin-top:var(--space-5);}
.fdy-step-nav{display:flex;justify-content:space-between;gap:var(--space-2);margin-top:var(--space-5);}

/* Freeday — Table */
.fdy-table-wrap{overflow-x:auto;border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-1);background:var(--color-surface);}
.fdy-table{width:100%;border-collapse:collapse;font-size:var(--text-sm);}
.fdy-table caption{text-align:left;padding:var(--space-3) var(--space-4);font-weight:var(--weight-semibold);color:var(--color-text);}
.fdy-table th{text-align:left;padding:var(--space-3) var(--space-4);font-size:var(--text-xs);font-weight:var(--weight-semibold);text-transform:uppercase;letter-spacing:var(--tracking-wide);color:var(--color-text-muted);background:var(--color-surface-2);border-bottom:var(--bw) solid var(--color-border);white-space:nowrap;}
.fdy-table td{padding:var(--space-3) var(--space-4);border-bottom:var(--bw) solid var(--color-border-muted);color:var(--color-text);}
.fdy-table tbody tr:last-child td{border-bottom:0;}
.fdy-table tbody tr{transition:background-color var(--dur-fast) var(--ease-standard);}
.fdy-table tbody tr:hover{background:var(--color-surface-2);}
/* Monospace data — ids, codes, IPs, timestamps. Alignment-neutral so it works in any cell
   or inline (`<span class="fdy-mono">`), not just numeric columns. */
.fdy-mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;}
/* Numeric cells are mono + right-aligned. Kept self-contained (not composed from .fdy-mono)
   so existing single-class markup keeps working. */
.fdy-table__num{text-align:right;font-variant-numeric:tabular-nums;font-family:var(--font-mono);}
/* Loading / empty state cell (FdyTable spans it across all columns). */
.fdy-table__state{text-align:center;color:var(--color-text-muted);padding:var(--space-6) var(--space-4);}
/* Activatable row (FdyTable rowActivatable): pointer + keyboard focus ring. The hover tint already
   comes from the base `.fdy-table tbody tr:hover` rule, so this only adds the affordance + focus. */
.fdy-table__row--activatable{cursor:pointer;}
.fdy-table__row--activatable:focus-visible{outline:2px solid var(--color-primary);outline-offset:-2px;}
/* Expandable detail row (FdyTable row-detail slot): a muted panel under its row, no hover tint. */
.fdy-table__detailrow>td,.fdy-table__detailrow:hover>td{background:var(--color-surface-2);}
.fdy-table th[aria-sort]{cursor:pointer;}
.fdy-table th[aria-sort="ascending"]::after{content:" ↑";color:var(--color-primary);}
.fdy-table th[aria-sort="descending"]::after{content:" ↓";color:var(--color-primary);}

/* Sortable header button (accessible click target inside th) */
.fdy-table__sortbtn{appearance:none;border:0;background:transparent;font:inherit;color:inherit;text-transform:inherit;letter-spacing:inherit;font-weight:inherit;cursor:pointer;padding:0;}
.fdy-table__sortbtn:hover{color:var(--color-text);}
.fdy-table__sortbtn:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}

/* Selection column + selected row */
.fdy-table__selcol{width:1px;white-space:nowrap;}
.fdy-table tbody tr[aria-selected="true"],.fdy-table tbody tr[aria-selected="true"]:hover{background:var(--color-primary-soft);}

/* Data-table shell (toolbar + scroll + footer stay put while the table scrolls) */
.fdy-datatable{border:var(--bw) solid var(--color-border);border-radius:var(--radius-lg);box-shadow:var(--shadow-1);background:var(--color-surface);overflow:hidden;}
.fdy-table-scroll{overflow-x:auto;}
.fdy-table-toolbar{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;padding:var(--space-3) var(--space-4);border-bottom:var(--bw) solid var(--color-border);}
.fdy-table-toolbar__search{max-width:18rem;}
.fdy-table-toolbar__spacer{flex:1;}
.fdy-table-toolbar__count{font-size:var(--text-sm);color:var(--color-text-muted);white-space:nowrap;}
.fdy-table-footer{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);flex-wrap:wrap;padding:var(--space-3) var(--space-4);border-top:var(--bw) solid var(--color-border);}
.fdy-table-footer__info{font-size:var(--text-sm);color:var(--color-text-muted);}

/* Column filter — funnel button injected (enhancer) or rendered (FdyTable) into a filterable <th> */
.fdy-table__filterwrap{display:inline-flex;align-items:center;vertical-align:middle;}
.fdy-table__filterbtn{appearance:none;display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;margin-left:var(--space-1);padding:0;vertical-align:middle;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-subtle);cursor:pointer;}
.fdy-table__filterbtn:hover{background:var(--color-surface-3);color:var(--color-text);}
.fdy-table__filterbtn:focus-visible{outline:none;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-table__filterbtn.is-active{color:var(--color-primary-strong);}
.fdy-table__filterbtn svg{width:.85rem;height:.85rem;}

/* Filter popover (position:fixed, appended to <body> so overflow can't clip it) */
.fdy-filter{position:fixed;z-index:130;min-width:14rem;max-width:18rem;padding:var(--space-3);background:var(--color-surface);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);text-transform:none;letter-spacing:normal;font-weight:var(--weight-regular);color:var(--color-text);}
.fdy-filter__title{font-size:var(--text-xs);font-weight:var(--weight-semibold);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:var(--tracking-wide);margin-bottom:var(--space-2);}
.fdy-filter__list{display:flex;flex-direction:column;gap:var(--space-1);max-height:12rem;overflow:auto;}
.fdy-filter__check{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;}
.fdy-filter__range{display:flex;align-items:center;gap:var(--space-2);}
.fdy-filter__range .fdy-input{width:6rem;}
.fdy-filter__foot{display:flex;justify-content:space-between;gap:var(--space-2);margin-top:var(--space-3);}

/* Bulk-action bar — appears above the table body once rows are selected */
.fdy-table-bulkbar{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-4);background:var(--color-primary-soft);border-bottom:var(--bw) solid var(--color-border);color:var(--color-primary-strong);font-size:var(--text-sm);}
.fdy-table-bulkbar[hidden]{display:none;}
.fdy-table-bulkbar__count{font-weight:var(--weight-semibold);white-space:nowrap;}
.fdy-table-bulkbar__spacer{flex:1;}
.fdy-table-bulkbar__actions{display:flex;gap:var(--space-2);}

/* Freeday — Tabs (WAI-ARIA APG) */
.fdy-tabs__list{display:flex;gap:var(--space-1);border-bottom:var(--bw) solid var(--color-border);overflow-x:auto;}
.fdy-tabs__tab{appearance:none;border:0;background:transparent;cursor:pointer;white-space:nowrap;font-family:var(--font-body);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted);padding:var(--space-3) var(--space-4);border-bottom:2px solid transparent;margin-bottom:-1px;transition:color var(--dur-fast) var(--ease-standard),border-color var(--dur-fast) var(--ease-standard);}
.fdy-tabs__tab:hover{color:var(--color-text);}
.fdy-tabs__tab:disabled,.fdy-tabs__tab[aria-disabled="true"]{opacity:.5;cursor:not-allowed;color:var(--color-text-muted);}
.fdy-tabs__tab:disabled:hover,.fdy-tabs__tab[aria-disabled="true"]:hover{color:var(--color-text-muted);}
.fdy-tabs__tab[aria-selected="true"]{color:var(--color-primary-strong);border-bottom-color:var(--color-primary);}
.fdy-tabs__tab:focus-visible{outline:none;border-radius:var(--radius-sm);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-tabs__panel{padding:var(--space-5) 0;}
.fdy-tabs__panel[hidden]{display:none;}
/* Reveal the newly-shown panel on tab switch (fade + rise), reduced-motion gated. */
@media (prefers-reduced-motion:no-preference){.fdy-tabs__panel:not([hidden]){animation:fdy-combo-in var(--dur-base) var(--ease-standard);}}

/* Freeday — Timeline (vertical event feed: dot markers on a connector line). Pure CSS. */
.fdy-timeline{list-style:none;margin:0;padding:0;}
.fdy-timeline__item{position:relative;padding:0 0 var(--space-5) var(--space-6);border-left:2px solid var(--color-border);}
.fdy-timeline__item:last-child{border-left-color:transparent;padding-bottom:0;}
.fdy-timeline__marker{position:absolute;left:0;top:.15rem;transform:translateX(-50%);width:.85rem;height:.85rem;border-radius:var(--radius-full);background:var(--color-primary);border:2px solid var(--color-surface);box-shadow:0 0 0 2px var(--color-border);}
.fdy-timeline__item--success .fdy-timeline__marker{background:var(--color-success);}
.fdy-timeline__item--warning .fdy-timeline__marker{background:var(--color-warning);}
.fdy-timeline__item--danger .fdy-timeline__marker{background:var(--color-danger);}
.fdy-timeline__item--muted .fdy-timeline__marker{background:var(--color-border-strong);}
.fdy-timeline__time{font-size:var(--text-xs);color:var(--color-text-muted);font-variant-numeric:tabular-nums;}
.fdy-timeline__title{margin:0;font-size:var(--text-sm);font-weight:var(--weight-semibold);color:var(--color-text);}
.fdy-timeline__text{margin:var(--space-1) 0 0;font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal);}

/* Freeday — Time picker (input-styled trigger + scrollable time-list popover).
 * Built by freeday-timepicker.js from an empty [data-fdy-timepicker] wrapper.
 * Trigger visual mirrors the date picker for a consistent control family. */
.fdy-timepicker{position:relative;display:inline-block;width:100%;max-width:11rem;}
.fdy-timepicker__trigger{display:inline-flex;align-items:center;gap:var(--space-2);width:100%;height:var(--control-h);padding:0 var(--space-3);text-align:left;cursor:pointer;font-family:var(--font-body);font-size:var(--text-sm);color:var(--color-text);background:var(--color-surface);border:1.5px solid var(--color-control-border);border-radius:var(--radius-md);box-shadow:inset 0 1px 2px rgba(16,14,30,.06);transition:border-color var(--dur-fast) var(--ease-standard),box-shadow var(--dur-fast) var(--ease-standard);}
.fdy-timepicker__trigger:hover{border-color:var(--color-text-muted);}
.fdy-timepicker__trigger:focus-visible{outline:none;border-color:var(--color-primary);box-shadow:inset 0 1px 2px rgba(16,14,30,.04),0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-timepicker__trigger.is-open{border-color:var(--color-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-primary) 26%,transparent);}
.fdy-timepicker--error .fdy-timepicker__trigger,.fdy-timepicker__trigger[aria-invalid="true"]{border-color:var(--color-danger);}
.fdy-timepicker--error .fdy-timepicker__trigger:focus-visible,.fdy-timepicker--error .fdy-timepicker__trigger.is-open,.fdy-timepicker__trigger[aria-invalid="true"]:focus-visible{border-color:var(--color-danger);box-shadow:0 0 0 3px color-mix(in srgb,var(--color-danger) 26%,transparent);}
.fdy-timepicker__trigger:disabled,.fdy-timepicker__trigger[aria-disabled="true"]{opacity:.5;cursor:not-allowed;}
.fdy-timepicker__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums;}
.fdy-timepicker__value--placeholder{color:var(--color-text-subtle);}
.fdy-timepicker__icon{flex:none;display:inline-flex;color:var(--color-text-subtle);}
.fdy-timepicker__icon svg{display:block;width:1.05rem;height:1.05rem;}

.fdy-timepicker__panel{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:130;min-width:100%;max-height:15rem;overflow-y:auto;margin:0;padding:var(--space-1);list-style:none;background:var(--color-surface);color:var(--color-text);border:var(--bw) solid var(--color-border-strong);border-radius:var(--radius-md);box-shadow:var(--shadow-3);}
.fdy-timepicker__panel[hidden]{display:none;}
.fdy-timepicker__panel:focus-visible{outline:none;}
.fdy-timepicker__opt{display:flex;align-items:center;padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-sm);color:var(--color-text);font-variant-numeric:tabular-nums;cursor:pointer;white-space:nowrap;}
.fdy-timepicker__opt:hover,.fdy-timepicker__opt.is-active{background:var(--color-surface-3);}
.fdy-timepicker__opt[aria-selected="true"]{background:var(--color-primary-soft);color:var(--color-primary-strong);font-weight:var(--weight-semibold);}
@media (prefers-reduced-motion:no-preference){.fdy-timepicker__panel:not([hidden]){animation:fdy-combo-in var(--dur-fast) var(--ease-standard);}}

/* Freeday — Toast (transient notification) */
.fdy-toast-region{position:fixed;z-index:200;bottom:var(--space-5);right:var(--space-5);display:flex;flex-direction:column;gap:var(--space-3);width:min(24rem,calc(100vw - var(--space-8)));pointer-events:none;}
.fdy-toast{pointer-events:auto;display:flex;gap:var(--space-3);align-items:flex-start;padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);background:var(--color-inverse-surface);color:var(--color-inverse-text);box-shadow:var(--shadow-3);}
.fdy-toast__accent{flex:none;width:.25rem;align-self:stretch;border-radius:var(--radius-full);background:var(--color-primary);}
.fdy-toast--success .fdy-toast__accent{background:var(--color-success);}
.fdy-toast--warning .fdy-toast__accent{background:var(--color-warning);}
.fdy-toast--danger .fdy-toast__accent{background:var(--color-danger);}
.fdy-toast--info .fdy-toast__accent{background:var(--color-info);}
.fdy-toast__body{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1);font-size:var(--text-sm);}
.fdy-toast__title{font-weight:var(--weight-semibold);}
.fdy-toast__text{opacity:.88;line-height:var(--leading-normal);}
.fdy-toast__close{flex:none;border:0;background:transparent;color:var(--color-inverse-text);opacity:.7;cursor:pointer;font-size:var(--text-lg);line-height:1;padding:0 var(--space-1);border-radius:var(--radius-sm);}
.fdy-toast__close:hover{opacity:1;}
.fdy-toast__close:focus-visible{outline:none;opacity:1;box-shadow:0 0 0 3px color-mix(in srgb,var(--color-inverse-text) 40%,transparent);}
.fdy-toast.is-leaving{opacity:0;transform:translateX(16px);transition:opacity var(--dur-base) var(--ease-standard),transform var(--dur-base) var(--ease-standard);}
@media (prefers-reduced-motion:no-preference){.fdy-toast{animation:fdy-toast-in var(--dur-base) var(--ease-spring);}}
@keyframes fdy-toast-in{from{opacity:0;transform:translateY(14px);}to{opacity:1;transform:none;}}

/* Freeday — Tooltip (CSS-only, hover/focus) */
.fdy-tooltip-wrap{position:relative;display:inline-flex;}
.fdy-tooltip{position:absolute;bottom:calc(100% + var(--space-2));left:50%;z-index:150;max-width:16rem;padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);font-size:var(--text-xs);font-weight:var(--weight-medium);line-height:var(--leading-snug);color:var(--color-inverse-text);background:var(--color-inverse-surface);box-shadow:var(--shadow-2);opacity:0;visibility:hidden;pointer-events:none;transform:translateX(-50%) translateY(4px);transition:opacity var(--dur-fast) var(--ease-standard),transform var(--dur-fast) var(--ease-standard);}
.fdy-tooltip::after{content:"";position:absolute;top:100%;left:50%;transform:translateX(-50%);border:.3rem solid transparent;border-top-color:var(--color-inverse-surface);}
.fdy-tooltip-wrap:hover .fdy-tooltip,.fdy-tooltip-wrap:focus-within .fdy-tooltip{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);}
@media (prefers-reduced-motion:reduce){.fdy-tooltip{transition:none;transform:translateX(-50%);}}

/* Freeday — Tree view (hierarchy via nested native <details>: keyboard-toggle, zero-JS).
 * Branches expand/collapse; leaves are plain rows. Chevron + optional folder/file icons. */
.fdy-tree{list-style:none;margin:0;padding:0;font-size:var(--text-sm);}
.fdy-tree ul{list-style:none;margin:0;padding-left:var(--space-4);}
.fdy-tree__branch > summary,.fdy-tree__leaf{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);color:var(--color-text);}
.fdy-tree__branch > summary{list-style:none;cursor:pointer;}
.fdy-tree__branch > summary::-webkit-details-marker{display:none;}
.fdy-tree__branch > summary:hover,.fdy-tree__leaf:hover{background:var(--color-surface-2);}
.fdy-tree__branch > summary:focus-visible{outline:none;box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-primary) 45%,transparent);}
.fdy-tree__chevron{flex:none;width:.9rem;height:.9rem;color:var(--color-text-subtle);transition:transform var(--dur-fast) var(--ease-standard);}
.fdy-tree__branch[open] > summary .fdy-tree__chevron{transform:rotate(90deg);}
.fdy-tree__icon{flex:none;width:1rem;height:1rem;color:var(--color-text-muted);}
.fdy-tree__leaf{padding-left:calc(var(--space-2) * 2 + .9rem);}
.fdy-tree__leaf .fdy-tree__icon{color:var(--color-text-subtle);}
/* Disabled row (branch summary or leaf): dimmed, no hover, not interactive. */
.fdy-tree__leaf[aria-disabled="true"],.fdy-tree__branch[aria-disabled="true"] > summary{opacity:.5;cursor:not-allowed;pointer-events:none;}

/* Checkbox variant — a selectable tree (cascading parent/child via freeday-tree.js).
 * A native <input class="fdy-checkbox"> sits at the start of every row; a partially
 * selected branch shows the native :indeterminate dash. The checkbox stops click
 * propagation, so toggling selection never expands/collapses the branch. */
.fdy-tree--checkbox .fdy-tree__check{flex:none;}
.fdy-tree--checkbox .fdy-tree__leaf{padding-left:calc(var(--space-2) + .9rem + var(--space-2));}
