/* =====================================================================
   Clasa 0B — base + reusable components (v3.1)
   ---------------------------------------------------------------------
   Load order: tokens.css -> base.css -> screen CSS.
   All component classes are prefixed "ui-" (BEM-ish: .ui-block__elem,
   .ui-block--modifier, state classes .is-*). Screens compose these and
   only add layout of their own.
   Rules: colours ONLY from tokens.css · font sizes ONLY from --fs-*
   tokens (rem) · no opacity < 1 on text · text-bearing pills use
   min-height, never height.
   ===================================================================== */

/* ---------- 1. Reset ------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%; text-size-adjust: 100%;
  /* keep focused elements clear of the sticky app bar and fixed tab bar (WCAG 2.4.11) */
  scroll-padding-top: calc(var(--appbar-h) + var(--safe-top) + 16px);
  scroll-padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom) + 16px);
}
@media (min-width: 1100px) { html { scroll-padding-top: 16px; scroll-padding-bottom: 16px; } }
body {
  margin: 0; min-height: 100dvh;
  background: var(--paper); color: var(--ink);
  font-family: var(--font-ui); font-size: var(--fs-body); line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility; overflow-x: hidden;
}
h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }
h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: inherit; line-height: 1.2; }
img, svg, video, canvas { display: block; max-width: 100%; }
button, input, textarea, select { font: inherit; color: inherit; letter-spacing: inherit; }
button { background: none; border: 0; padding: 0; cursor: pointer; }
button:disabled, [aria-disabled="true"] { cursor: not-allowed; }
a { color: inherit; text-decoration: none; }
button, a, input, select, textarea, label, summary { -webkit-tap-highlight-color: transparent; }
table { border-collapse: collapse; }
hr { border: 0; }
fieldset.ui-fieldset { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: var(--gap, var(--sp-2)); }
fieldset.ui-fieldset > legend { padding: 0; margin-bottom: var(--sp-2); float: left; width: 100%; }
fieldset.ui-fieldset > legend + * { clear: both; }
::selection { background: var(--accent-soft); color: var(--ink); }

/* Focus: one ring everywhere (≥3:1 on all surfaces). No border-radius here —
   the ring follows the element's own shape. */
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
:focus:not(:focus-visible) { outline: none; }
/* Inside clipping containers (overflow hidden/auto) draw the ring INSIDE. */
.ui-row:focus-visible, .ui-tab:focus-visible, .ui-seg__btn:focus-visible, .ui-photo:focus-visible,
.ui-month__cell:focus-visible, .ui-minical__day:focus-visible, .ui-daystrip__day:focus-visible,
.ui-nav-item:focus-visible, .ui-cal-ev:focus-visible, .ui-card--pad-0 :focus-visible, .ui-list :focus-visible,
.ui-table-wrap :focus-visible { outline-offset: -2px; }
.ui-table tbody tr:focus-within { outline: 2px solid var(--focus); outline-offset: -2px; }

/* Scroll containers are positioned so absolutely-positioned sr-only text inside them is clipped, not page-widening. */
.ui-table-wrap, .ui-tabs, .ui-chips--scroll, .ui-seg, .ui-sheet__body { position: relative; }
.ui-sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.ui-skip { position: fixed; left: var(--sp-4); top: -80px; z-index: var(--z-tooltip); background: var(--inverse-surface); color: var(--on-inverse-surface); padding: 10px 16px; border-radius: var(--r-sm); font-weight: var(--fw-semibold); }
.ui-skip:focus { top: calc(var(--sp-4) + var(--safe-top)); }
/* Input-modality helpers: copy that only makes sense with a mouse vs a finger. */
@media (pointer: coarse) { .ui-only-fine { display: none !important; } }
@media (pointer: fine), (pointer: none) { .ui-only-coarse { display: none !important; } }

/* ---------- 2. Typography ------------------------------------------ */
/* Display = serif (Newsreader -> Georgia): page titles, hero, section
   titles. Everything else is the UI sans. */
.ui-display-xl, .ui-display-l, .ui-display-m, .ui-display-s {
  font-family: var(--font-display); font-weight: var(--fw-regular); letter-spacing: var(--ls-display);
  font-optical-sizing: auto; color: var(--ink); text-wrap: balance;
}
.ui-display-xl { font-size: var(--fs-display-xl); line-height: var(--lh-display-xl); }
.ui-display-l  { font-size: var(--fs-display-l);  line-height: var(--lh-display-l); }
.ui-display-m  { font-size: var(--fs-display-m);  line-height: var(--lh-display-m); }
.ui-display-s  { font-size: var(--fs-display-s);  line-height: var(--lh-display-s); }
.ui-display-xl em, .ui-display-l em, .ui-display-m em { font-style: italic; color: var(--primary-ink); }
.ui-title-l { font-size: var(--fs-title-l); line-height: var(--lh-title-l); font-weight: var(--fw-semibold); letter-spacing: var(--ls-tight); }
.ui-title   { font-size: var(--fs-title);   line-height: var(--lh-title);   font-weight: var(--fw-semibold); letter-spacing: var(--ls-tight); }
.ui-body    { font-size: var(--fs-body);    line-height: var(--lh-body); }
.ui-body-s  { font-size: var(--fs-body-s);  line-height: var(--lh-body-s); }
.ui-caption { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--muted); }
.ui-label-s { font-size: var(--fs-label-s); line-height: var(--lh-label-s); font-weight: var(--fw-semibold); }
/* Eyebrow: decorative context label. Never the ONLY carrier of key data
   (e.g. today's date must also appear as a title-sized line). */
.ui-eyebrow {
  display: block; font-size: var(--fs-eyebrow); line-height: 1.3; font-weight: var(--fw-bold);
  letter-spacing: var(--ls-eyebrow); text-transform: uppercase; color: var(--muted);
}
.ui-muted { color: var(--muted); }
.ui-num { font-variant-numeric: tabular-nums; }
.ui-prose { max-width: var(--reading-max); color: var(--ink-2); }
.ui-prose p + p { margin-top: .8em; }
.ui-link { color: var(--primary-ink); font-weight: var(--fw-semibold); text-decoration: underline; text-decoration-color: color-mix(in srgb, currentColor 35%, transparent); text-underline-offset: 3px; }
.ui-link:hover { text-decoration-color: currentColor; }
.ui-kbd {
  display: inline-flex; align-items: center; justify-content: center; min-width: 22px; min-height: 22px; padding: 0 6px;
  font: var(--fw-semibold) var(--fs-label-s)/1 var(--font-ui); color: var(--muted); background: var(--surface);
  border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: var(--r-xs);
}
@media (pointer: coarse) { .ui-kbd { display: none; } } /* no keyboard shortcuts on touch */

/* ---------- 3. Icons ------------------------------------------------ */
/* Produced by App.ui.icon(name). 24px grid, stroke 1.7, round caps.
   Flutter: ship as SVG (flutter_svg) so the active stroke-width works. */
.ui-i { width: 20px; height: 20px; flex-shrink: 0; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.ui-i--xs { width: 14px; height: 14px; }
.ui-i--sm { width: 16px; height: 16px; }
.ui-i--lg { width: 24px; height: 24px; }
.ui-i--xl { width: 32px; height: 32px; stroke-width: 1.5; }

/* ---------- 4. Layout helpers -------------------------------------- */
.ui-page { width: 100%; max-width: var(--content-max); margin-inline: auto; padding-inline: calc(var(--gutter) + var(--safe-left)) calc(var(--gutter) + var(--safe-right)); }
.ui-stack { display: flex; flex-direction: column; gap: var(--gap, var(--sp-4)); }
.ui-cluster { display: flex; flex-wrap: wrap; align-items: center; gap: var(--gap, var(--sp-2)); }
.ui-spread { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.ui-grid { display: grid; gap: var(--gap, var(--sp-4)); grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--min, 260px)), 1fr)); }
.ui-divider { height: 1px; background: var(--line); margin-block: var(--sp-4); }
.ui-divider--label { display: flex; align-items: center; gap: var(--sp-3); height: auto; background: none; font-size: var(--fs-caption); color: var(--muted); }
.ui-divider--label::before, .ui-divider--label::after { content: ""; flex: 1; height: 1px; background: var(--line); }

/* ---------- 5. Buttons ---------------------------------------------- */
/* <button class="ui-btn ui-btn--primary">{icon} Etichetă</button>
   Variants: --primary | --secondary | --soft | --ghost | --danger | --danger-soft
   Sizes: --sm (36px; grows to 44 on touch) | default 44 | --lg 52 ; --block = full width
   SHAPE RULE: text buttons --r-md (pill only with --pill) · icon buttons
   are circles · FAB --r-fab. One "add" affordance per screen. */
.ui-btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--touch); max-width: 100%; padding: 6px 18px; border-radius: var(--r-md); border: 1px solid transparent; text-align: center;
  font-size: var(--fs-button); font-weight: var(--fw-semibold); line-height: var(--lh-button); letter-spacing: -.005em; /* wraps instead of overflowing under large text */
  background: var(--surface-3); color: var(--ink); user-select: none;
  transition: background-color var(--dur-1) var(--ease-standard), border-color var(--dur-1), box-shadow var(--dur-2), transform var(--dur-1) var(--ease-standard), color var(--dur-1);
}
.ui-btn .ui-i { width: 18px; height: 18px; margin-inline: -2px; }
.ui-btn:active:not(:disabled) { transform: scale(.975); }
.ui-btn:disabled, .ui-btn[aria-disabled="true"] { opacity: .45; }
.ui-btn--primary { background: var(--primary); color: var(--on-primary); box-shadow: var(--sh-primary); }
.ui-btn--primary:hover:not(:disabled) { background: var(--primary-hover); }
.ui-btn--primary:active:not(:disabled) { background: var(--primary-press); }
.ui-btn--secondary { background: var(--surface); border-color: var(--line-strong); color: var(--ink); box-shadow: var(--sh-1); }
.ui-btn--secondary:hover:not(:disabled) { background: var(--surface-2); border-color: var(--control-border); }
.ui-btn--soft { background: var(--primary-soft); color: var(--on-primary-soft); }
.ui-btn--soft:hover:not(:disabled) { background: var(--primary-soft-2); }
.ui-btn--ghost { background: transparent; color: var(--ink-2); padding-inline: 12px; }
.ui-btn .ui-i, .ui-btn__count { flex-shrink: 0; }
.ui-btn--ghost:hover:not(:disabled) { background: var(--surface-3); color: var(--ink); }
.ui-btn--danger { background: var(--danger); color: var(--on-danger); }
.ui-btn--danger:hover:not(:disabled) { filter: brightness(.94); }
.ui-btn--danger-soft { background: var(--danger-soft); color: var(--danger-ink); }
.ui-btn--sm { min-height: 36px; padding: 4px 12px; font-size: var(--fs-label); border-radius: var(--r-sm); }
@media (pointer: coarse) { .ui-btn--sm { min-height: var(--touch); } }
.ui-btn--lg { min-height: 52px; padding: 8px 24px; font-size: var(--fs-body); border-radius: var(--r-md); }
.ui-btn--block { display: flex; width: 100%; }
.ui-btn--pill { border-radius: var(--r-pill); }
.ui-btn__count { font-size: var(--fs-label-s); font-weight: var(--fw-bold); padding: 1px 6px; border-radius: var(--r-pill); background: color-mix(in srgb, currentColor 18%, transparent); }

/* Icon-only button — ALWAYS give aria-label. 44×44 circle.
   Sibling --sm buttons need gap ≥ 8px (their 44px hit areas must not overlap). */
.ui-icon-btn {
  position: relative; display: inline-grid; place-items: center; width: var(--touch); height: var(--touch); flex-shrink: 0;
  border-radius: var(--r-pill); color: var(--ink-2); background: transparent; border: 1px solid transparent;
  transition: background-color var(--dur-1), color var(--dur-1), transform var(--dur-1) var(--ease-standard);
}
.ui-icon-btn:hover:not(:disabled) { background: var(--surface-3); color: var(--ink); }
.ui-icon-btn:active:not(:disabled) { transform: scale(.94); }
.ui-icon-btn--outlined { background: var(--surface); border-color: var(--line-strong); box-shadow: var(--sh-1); }
.ui-icon-btn--primary { background: var(--primary); color: var(--on-primary); }
.ui-icon-btn--primary:hover:not(:disabled) { background: var(--primary-hover); color: var(--on-primary); }
.ui-icon-btn--round { border-radius: var(--r-pill); } /* kept for compatibility — all icon buttons are round */
.ui-icon-btn--sm { width: 36px; height: 36px; }
.ui-icon-btn--sm::after { content: ""; position: absolute; inset: -4px; border-radius: 50%; } /* 44px hit area */
.ui-icon-btn .ui-dot { position: absolute; top: 9px; right: 9px; }

/* Floating action button (M3 shape r16). Extended: text inside + --extended */
.ui-fab {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  width: 56px; height: 56px; border-radius: var(--r-fab); background: var(--primary); color: var(--on-primary);
  box-shadow: var(--sh-fab); transition: transform var(--dur-2) var(--ease-spring), background-color var(--dur-1);
}
.ui-fab .ui-i { width: 24px; height: 24px; stroke-width: 2; }
.ui-fab:hover { background: var(--primary-hover); }
.ui-fab:active { transform: scale(.93); }
.ui-fab--extended { width: auto; padding: 0 20px 0 16px; font-weight: var(--fw-semibold); font-size: var(--fs-button); }
.ui-fab--fixed { position: fixed; right: calc(var(--sp-4) + var(--safe-right)); bottom: calc(var(--tabbar-h) + var(--safe-bottom) + var(--sp-4)); z-index: var(--z-fab); }

/* Counters & dots. A dot is visual only: pair it with sr-only text ("3 noi"). */
.ui-count { display: inline-grid; place-items: center; min-width: 20px; min-height: 20px; padding: 2px 6px; border-radius: var(--r-pill); font-size: var(--fs-label-s); font-weight: var(--fw-bold); line-height: 1; background: var(--surface-3); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.ui-count--accent { background: var(--primary); color: var(--on-primary); }
.ui-count--danger { background: var(--danger); color: var(--on-danger); }
.ui-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px var(--surface); }
.ui-dot--accent { background: var(--accent); }
.ui-dot--ok { background: var(--success); }
.ui-badge { display: inline-flex; align-items: center; gap: 4px; min-height: 22px; padding: 2px 8px; border-radius: var(--r-xs); font-size: var(--fs-caption); font-weight: var(--fw-semibold); line-height: var(--lh-label); background: var(--surface-3); color: var(--ink-2); white-space: nowrap; }

/* ---------- 6. Form controls --------------------------------------- */
/* Pattern (hint/error are DESCRIPTIONS, not part of the name):
   <div class="ui-field">
     <label class="ui-label" for="f-titlu">Titlu</label>
     <input class="ui-input" id="f-titlu" aria-describedby="f-titlu-hint">
     <p class="ui-hint" id="f-titlu-hint">Apare în calendar.</p>
   </div>
   Error: .is-invalid on .ui-field + aria-invalid="true" on the control; the
   hint gets an alert icon (App.ui.field() builds all of this).
   Groups of radios/checkboxes: <fieldset class="ui-fieldset"><legend class="ui-label">…</legend> */
.ui-field { display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; min-width: 0; }
.ui-label { font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--fw-semibold); color: var(--ink-2); }
.ui-label__opt { font-weight: var(--fw-regular); color: var(--muted); }
.ui-hint { display: flex; align-items: flex-start; gap: 6px; font-size: var(--fs-caption); color: var(--muted); line-height: var(--lh-caption); }
.ui-hint .ui-i { width: 15px; height: 15px; margin-top: 1px; }
.ui-field.is-invalid .ui-hint { color: var(--danger-ink); font-weight: var(--fw-medium); }
.ui-field.is-invalid .ui-input, .ui-field.is-invalid .ui-textarea, .ui-field.is-invalid .ui-select { border-color: var(--danger); box-shadow: inset 0 0 0 1px var(--danger); }

.ui-input, .ui-textarea, .ui-select {
  width: 100%; min-height: var(--touch); padding: 10px 14px;
  background: var(--surface); color: var(--ink); border: 1px solid var(--control-border); border-radius: 12px;
  font-size: var(--fs-input); /* 16px avoids iOS zoom on focus */ line-height: 1.4;
  transition: border-color var(--dur-1), box-shadow var(--dur-2);
}
.ui-input::placeholder, .ui-textarea::placeholder { color: var(--muted); }
.ui-input:hover, .ui-textarea:hover, .ui-select:hover { border-color: var(--ink-2); }
.ui-input:focus-visible, .ui-textarea:focus-visible, .ui-select:focus-visible,
.ui-input:focus, .ui-textarea:focus, .ui-select:focus { outline: none; border-color: var(--primary-ink); box-shadow: var(--focus-ring); }
.ui-input:disabled, .ui-textarea:disabled, .ui-select:disabled { background: var(--surface-3); color: var(--muted); border-color: var(--line-strong); }
.ui-textarea { min-height: 104px; resize: vertical; }

.ui-select-wrap { position: relative; display: block; }
.ui-select { appearance: none; -webkit-appearance: none; padding-right: 40px; cursor: pointer; }
.ui-select-wrap::after {
  content: ""; position: absolute; right: 17px; top: 50%; width: 7px; height: 7px; pointer-events: none;
  border-right: 1.7px solid var(--muted); border-bottom: 1.7px solid var(--muted); transform: translateY(-70%) rotate(45deg);
}

/* Search: <label class="ui-search">{icon search}<input type="search" placeholder="Caută…" aria-label="Caută"><kbd class="ui-kbd">/</kbd></label>
   Keep placeholders short ("Caută…"); the kbd hint hides on touch. */
.ui-search {
  position: relative; display: flex; align-items: center; gap: var(--sp-2); min-height: var(--touch); padding: 0 12px 0 14px;
  background: var(--surface-3); border: 1px solid transparent; border-radius: var(--r-pill); color: var(--muted);
  transition: background-color var(--dur-1), border-color var(--dur-1), box-shadow var(--dur-2);
}
.ui-search:focus-within { background: var(--surface); border-color: var(--primary-ink); box-shadow: var(--focus-ring); }
.ui-search input { flex: 1; min-width: 0; border: 0; background: transparent; outline: none; font-size: var(--fs-input); color: var(--ink); padding: 10px 0; text-overflow: ellipsis; }
.ui-search input::placeholder { color: var(--muted); }
.ui-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

/* Checkbox & radio: <label class="ui-check"><input type="checkbox"><span class="ui-check__text">Text<small>detaliu</small></span></label> */
.ui-check, .ui-radio { display: inline-flex; align-items: flex-start; gap: var(--sp-3); min-height: var(--touch); padding: 11px 0; cursor: pointer; font-size: var(--fs-body); line-height: 1.4; }
.ui-check input, .ui-radio input {
  appearance: none; -webkit-appearance: none; flex-shrink: 0; width: 22px; height: 22px; margin: -1px 0 0; display: grid; place-items: center;
  background: var(--surface); border: 2px solid var(--control-border); cursor: pointer;
  transition: background-color var(--dur-1), border-color var(--dur-1), box-shadow var(--dur-1);
}
.ui-check input { border-radius: 7px; }
.ui-radio input { border-radius: 50%; }
.ui-check input::after { content: ""; width: 6px; height: 11px; margin-top: -2px; border: solid var(--on-primary); border-width: 0 2px 2px 0; transform: rotate(45deg) scale(0); transition: transform var(--dur-2) var(--ease-spring); }
.ui-radio input::after { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--on-primary); transform: scale(0); transition: transform var(--dur-2) var(--ease-spring); }
.ui-check input:checked, .ui-radio input:checked { background: var(--primary); border-color: var(--primary); }
.ui-check input:checked::after { transform: rotate(45deg) scale(1); }
.ui-radio input:checked::after { transform: scale(1); }
.ui-check input:indeterminate { background: var(--primary); border-color: var(--primary); }
.ui-check input:indeterminate::after { width: 10px; height: 0; margin: 0; border-width: 0 0 2px; transform: none; }
.ui-check input:hover:not(:checked), .ui-radio input:hover:not(:checked) { border-color: var(--ink-2); }
.ui-check input:focus-visible, .ui-radio input:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.ui-check__text small, .ui-radio__text small { display: block; color: var(--muted); font-size: var(--fs-caption); margin-top: 2px; }

/* Switch (M3 geometry 52×32): <label class="ui-switch"><span>Text</span><input type="checkbox" role="switch"></label>
   Off = outlined track + small outline-coloured thumb; on = filled track + large on-primary thumb. */
.ui-switch { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-4); min-height: var(--touch); cursor: pointer; }
.ui-switch input {
  appearance: none; -webkit-appearance: none; position: relative; flex-shrink: 0; width: 52px; height: 32px; margin: 0; border-radius: var(--r-pill);
  background: var(--surface-3); border: 2px solid var(--control-border); cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-standard), border-color var(--dur-2);
}
.ui-switch input::before {
  content: ""; position: absolute; top: 50%; left: 4px; width: 16px; height: 16px; margin-top: -8px; border-radius: 50%;
  background: var(--control-border);
  transition: transform var(--dur-2) var(--ease-spring), width var(--dur-2), height var(--dur-2), margin var(--dur-2), left var(--dur-2), background-color var(--dur-2);
}
.ui-switch input:checked { background: var(--primary); border-color: var(--primary); }
.ui-switch input:checked::before { left: 2px; width: 24px; height: 24px; margin-top: -12px; transform: translateX(20px); background: var(--on-primary); box-shadow: var(--sh-1); }
.ui-switch input:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.ui-switch input:disabled { opacity: .45; }

/* Segmented control (also segmented tabs). iOS-style pill — Flutter: custom widget.
   <div class="ui-seg" role="radiogroup" aria-label="…"><button class="ui-seg__btn" role="radio" aria-checked="true">Zi</button>…</div>
   Wire with App.ui.bindSegmented(el, onChange) or build with App.ui.segmented({...}). */
.ui-seg { display: inline-flex; gap: 2px; padding: 3px; border-radius: 13px; background: var(--surface-3); max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.ui-seg::-webkit-scrollbar { display: none; }
.ui-seg--block { display: flex; width: 100%; }
.ui-seg--block .ui-seg__btn { flex: 1; }
.ui-seg__btn {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 38px; padding: 4px 14px;
  border-radius: 10px; font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--fw-medium); color: var(--muted); white-space: nowrap;
  transition: background-color var(--dur-2) var(--ease-standard), color var(--dur-1), box-shadow var(--dur-2);
}
.ui-seg__btn::after { content: ""; position: absolute; inset: -3px 0; } /* 44px hit area */
.ui-seg__btn .ui-i { width: 16px; height: 16px; }
.ui-seg__btn:hover { color: var(--ink); }
/* Selected: surface pill + hairline + primary text — never surface contrast alone. */
.ui-seg__btn[aria-checked="true"], .ui-seg__btn[aria-selected="true"], .ui-seg__btn[aria-pressed="true"] {
  background: var(--surface); color: var(--primary-ink); font-weight: var(--fw-semibold); box-shadow: 0 0 0 1px var(--line-strong), var(--sh-1);
}

/* ---------- 7. Chips ------------------------------------------------ */
/* Filter pill: <button class="ui-chip" aria-pressed="false">Anunțuri <span class="ui-chip__count">3</span></button> */
.ui-chips { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.ui-chips--scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: calc(var(--gutter) * -1); padding: 4px var(--gutter); }
.ui-chips--scroll::-webkit-scrollbar { display: none; }
.ui-chip {
  position: relative; display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; min-height: 36px; padding: 4px 14px;
  border-radius: var(--r-pill); border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-2);
  font-size: var(--fs-label); line-height: var(--lh-label); font-weight: var(--fw-medium); white-space: nowrap;
  transition: background-color var(--dur-1), border-color var(--dur-1), color var(--dur-1), transform var(--dur-1);
}
button.ui-chip::after { content: ""; position: absolute; inset: -4px 0; }
.ui-chip .ui-i { width: 15px; height: 15px; }
.ui-chip:hover { border-color: var(--control-border); color: var(--ink); }
button.ui-chip:active { transform: scale(.97); }
.ui-chip[aria-pressed="true"], .ui-chip[aria-selected="true"], .ui-chip.is-active { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.ui-chip__count { font-size: var(--fs-label-s); font-weight: var(--fw-bold); font-variant-numeric: tabular-nums; }
.ui-chip__x { position: relative; display: grid; place-items: center; width: 20px; height: 20px; margin-right: -6px; border-radius: 50%; color: var(--ink-2); }
.ui-chip__x::after { content: ""; position: absolute; inset: -12px; border-radius: 50%; } /* 44px hit area */
.ui-chip__x:hover { background: var(--surface-3); }

/* Subject colour context. Put .ui-sub--{clr|mem|dp|mm|avap|eng|sport|rob|inot|muz|sah|dans}
   on any subject-aware component; it sets --_fg / --_bg for children.
   HUE MEANS SUBJECT. Nothing else uses these tints as a meaning. */
.ui-sub--clr   { --_fg: var(--sub-clr);   --_bg: var(--sub-clr-bg); }
.ui-sub--mem   { --_fg: var(--sub-mem);   --_bg: var(--sub-mem-bg); }
.ui-sub--dp    { --_fg: var(--sub-dp);    --_bg: var(--sub-dp-bg); }
.ui-sub--mm    { --_fg: var(--sub-mm);    --_bg: var(--sub-mm-bg); }
.ui-sub--avap  { --_fg: var(--sub-avap);  --_bg: var(--sub-avap-bg); }
.ui-sub--eng   { --_fg: var(--sub-eng);   --_bg: var(--sub-eng-bg); }
.ui-sub--sport { --_fg: var(--sub-sport); --_bg: var(--sub-sport-bg); }
.ui-sub--rob   { --_fg: var(--sub-rob);   --_bg: var(--sub-rob-bg); }
.ui-sub--inot  { --_fg: var(--sub-inot);  --_bg: var(--sub-inot-bg); }
.ui-sub--muz   { --_fg: var(--sub-muz);   --_bg: var(--sub-muz-bg); }
.ui-sub--sah   { --_fg: var(--sub-sah);   --_bg: var(--sub-sah-bg); }
.ui-sub--dans  { --_fg: var(--sub-dans);  --_bg: var(--sub-dans-bg); }
.ui-sub-tag { display: inline-flex; align-items: center; min-height: 22px; padding: 2px 8px; border-radius: var(--r-xs); font-size: var(--fs-label-s); line-height: 1.2; font-weight: var(--fw-bold); letter-spacing: .04em; background: var(--_bg, var(--surface-3)); color: var(--_fg, var(--muted)); }

/* Audience chip — who can see this. FORM encodes openness (see tokens.css):
   private = inverted solid · family/shared = tonal fill · class/school/staff = outline.
   Always icon + label; icon-only (--icon) only in dense tables, with role=img + tooltip.
   Built by App.ui.audienceChip(scope, label?, {viewer, size, iconOnly, button, attrs}). */
.ui-aud {
  --_fg: var(--aud-private-fg); --_bg: var(--aud-private-bg); --_bd: var(--aud-private-border);
  position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 3px 11px 3px 8px; max-width: 100%; min-width: 0;
  border-radius: var(--r-pill); border: 1.5px solid var(--_bd); background: var(--_bg); color: var(--_fg);
  font-size: var(--fs-label); font-weight: var(--fw-semibold); line-height: var(--lh-label); white-space: nowrap; vertical-align: middle;
}
.ui-aud > span:not(.ui-avatar) { overflow: hidden; text-overflow: ellipsis; }
.ui-aud .ui-i { width: 15px; height: 15px; stroke-width: 2; }
.ui-aud .ui-avatar { --_size: 20px; margin-left: -4px; font-size: var(--fs-label-s); }
.ui-aud--private { --_fg: var(--aud-private-fg); --_bg: var(--aud-private-bg); --_bd: var(--aud-private-border); }
.ui-aud--family  { --_fg: var(--aud-family-fg);  --_bg: var(--aud-family-bg);  --_bd: var(--aud-family-border); }
.ui-aud--shared  { --_fg: var(--aud-shared-fg);  --_bg: var(--aud-shared-bg);  --_bd: var(--aud-shared-border); }
.ui-aud--class   { --_fg: var(--aud-class-fg);   --_bg: var(--aud-class-bg);   --_bd: var(--aud-class-border); }
.ui-aud--school  { --_fg: var(--aud-school-fg);  --_bg: var(--aud-school-bg);  --_bd: var(--aud-school-border); }
.ui-aud--staff   { --_fg: var(--aud-staff-fg);   --_bg: var(--aud-staff-bg);   --_bd: var(--aud-staff-border); }
.ui-aud--lg { min-height: 32px; padding: 4px 13px 4px 10px; font-size: var(--fs-button); gap: 7px; }
.ui-aud--lg .ui-i { width: 16px; height: 16px; }
.ui-aud--icon { width: 28px; min-height: 28px; height: 28px; padding: 0; justify-content: center; }
button.ui-aud { cursor: pointer; }
button.ui-aud::after { content: ""; position: absolute; inset: -9px -2px; }

/* Audience picker ("Cine vede?") — radio cards inside a fieldset.
   Selection is shown the same way for every audience (primary ring + tint);
   the icon tile repeats the chip's form. App.ui.audiencePicker() builds it.
   <fieldset class="ui-fieldset"><legend class="ui-label">Cine vede?</legend>
     <label class="ui-aud-option ui-aud--class"><input type="radio" name="aud" value="class">
       <span class="ui-aud-option__icon">{icon}</span>
       <span class="ui-aud-option__text"><b>Clasa 0B</b><small>Părinții și personalul clasei</small>
         <span class="ui-aud-option__who">{avatarStack} 48 de persoane</span></span></label></fieldset>
   --compact: 48px rows, no description (desktop side panel); wrap in .ui-aud-grid for 2 columns. */
.ui-aud-option {
  position: relative; display: flex; align-items: center; gap: var(--sp-3); padding: 12px 14px; min-height: 60px; cursor: pointer;
  border: 1px solid var(--line-strong); border-radius: var(--r-md); background: var(--surface);
  transition: border-color var(--dur-1), background-color var(--dur-1), box-shadow var(--dur-1);
}
.ui-aud-option input { position: absolute; opacity: 0; pointer-events: none; }
.ui-aud-option__icon { display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: var(--_bg); color: var(--_fg); border: 1.5px solid var(--_bd); flex-shrink: 0; }
.ui-aud-option__text { display: grid; gap: 1px; min-width: 0; flex: 1; }
.ui-aud-option__text b { font-weight: var(--fw-semibold); font-size: var(--fs-body); line-height: 1.3; }
.ui-aud-option__text small { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--muted); }
.ui-aud-option__who { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: var(--fs-caption); color: var(--ink-2); font-weight: var(--fw-medium); }
.ui-aud-option__who .ui-avatar { --_size: 22px; }
.ui-aud-option::after { content: ""; margin-left: auto; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--control-border); flex-shrink: 0; transition: border var(--dur-1); }
.ui-aud-option:has(input:checked) { border-color: var(--primary-ink); background: var(--primary-soft); box-shadow: inset 0 0 0 1px var(--primary-ink); }
.ui-aud-option:has(input:checked)::after { border: 6px solid var(--primary-ink); }
.ui-aud-option:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.ui-aud-option--compact { min-height: 48px; padding: 8px 10px; gap: 10px; }
.ui-aud-option--compact .ui-aud-option__icon { width: 28px; height: 28px; }
.ui-aud-option--compact .ui-aud-option__icon .ui-i { width: 15px; height: 15px; }
.ui-aud-option--compact .ui-aud-option__text b { font-size: var(--fs-button); }
.ui-aud-option--compact .ui-aud-option__text small { display: none; }
.ui-aud-option--compact::after { width: 18px; height: 18px; }
.ui-aud-option--compact:has(input:checked)::after { border-width: 5px; }
.ui-aud-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-2); }

/* State badge — ingestion pipeline (App.ui.stateBadge). MONOCHROME:
   neutral pill, only the icon is coloured. Colour means audience/subject, not state. */
.ui-state {
  --_fg: var(--st-primit-fg); --_bg: var(--st-primit-bg);
  display: inline-flex; align-items: center; gap: 6px; min-height: 26px; padding: 3px 10px 3px 8px; border-radius: 8px;
  background: var(--_bg); border: 1px solid var(--line-strong); color: var(--ink);
  font-size: var(--fs-caption); line-height: var(--lh-label); font-weight: var(--fw-semibold); white-space: nowrap;
}
.ui-state .ui-i { width: 15px; height: 15px; stroke-width: 2; color: var(--_fg); }
.ui-state--primit    { --_fg: var(--st-primit-fg);    --_bg: var(--st-primit-bg); }
.ui-state--propus    { --_fg: var(--st-propus-fg);    --_bg: var(--st-propus-bg); }
.ui-state--verificat { --_fg: var(--st-verificat-fg); --_bg: var(--st-verificat-bg); }
.ui-state--publicat  { --_fg: var(--st-publicat-fg);  --_bg: var(--st-publicat-bg); }
.ui-state--respins   { --_fg: var(--st-respins-fg);   --_bg: var(--st-respins-bg); }
.ui-state--in_asteptare { --_fg: var(--st-primit-fg); --_bg: var(--st-primit-bg); }

/* Provenance — where did this come from, who touched it (App.ui.provenance).
   No text separators (they dangled on wrap): each part starts with its own icon. */
.ui-prov { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; font-size: var(--fs-caption); color: var(--muted); line-height: 1.3; }
.ui-prov__part { display: inline-flex; align-items: center; gap: 5px; }
.ui-prov__part .ui-i { width: 14px; height: 14px; }
.ui-prov__part--ai { color: var(--ai-ink); font-weight: var(--fw-semibold); }
.ui-prov__part--ok { color: var(--success-ink); font-weight: var(--fw-semibold); }
.ui-prov--boxed { padding: 8px 10px; border-radius: var(--r-sm); background: var(--surface-2); border: 1px dashed var(--line-strong); }
.ui-prov--stack { flex-direction: column; align-items: flex-start; }

/* ---------- 8. Avatars ---------------------------------------------- */
/* (App.ui.avatar) Colour c0…c7 is hashed from the name unless {color} is
   given (persist a parent's choice for the child). The palette avoids the
   semantic hues (AI violet, danger rose). */
.ui-avatar {
  --_size: 36px; position: relative; display: inline-grid; place-items: center; flex-shrink: 0;
  width: var(--_size); height: var(--_size); border-radius: 50%;
  background: var(--_bg, var(--surface-3)); color: var(--_fg, var(--ink-2));
  font-size: max(var(--fs-label-s), calc(var(--_size) * .38)); font-weight: var(--fw-semibold); letter-spacing: -.02em; line-height: 1; user-select: none;
}
.ui-avatar img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
.ui-avatar--xs { --_size: 24px; } .ui-avatar--sm { --_size: 30px; } .ui-avatar--lg { --_size: 48px; } .ui-avatar--xl { --_size: 72px; }
.ui-avatar--c0 { --_fg: var(--sub-dp);    --_bg: var(--sub-dp-bg); }
.ui-avatar--c1 { --_fg: var(--sub-eng);   --_bg: var(--sub-eng-bg); }
.ui-avatar--c2 { --_fg: var(--sub-avap);  --_bg: var(--sub-avap-bg); }
.ui-avatar--c3 { --_fg: var(--sub-dans);  --_bg: var(--sub-dans-bg); }
.ui-avatar--c4 { --_fg: var(--sub-rob);   --_bg: var(--sub-rob-bg); }
.ui-avatar--c5 { --_fg: var(--sub-sport); --_bg: var(--sub-sport-bg); }
.ui-avatar--c6 { --_fg: var(--sub-inot);  --_bg: var(--sub-inot-bg); }
.ui-avatar--c7 { --_fg: var(--sub-sah);   --_bg: var(--sub-sah-bg); }
/* Child: rounded square + thin ochre ring = "this is a child profile". */
.ui-avatar--child { border-radius: 30%; box-shadow: 0 0 0 1.5px var(--surface), 0 0 0 3px var(--accent); font-family: var(--font-display); font-weight: var(--fw-medium); font-size: max(var(--fs-label-s), calc(var(--_size) * .46)); }
.ui-avatar__badge { position: absolute; right: -3px; bottom: -3px; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; background: var(--primary); color: var(--on-primary); box-shadow: 0 0 0 2px var(--surface); }
.ui-avatar__badge .ui-i { width: 11px; height: 11px; stroke-width: 2.4; }
.ui-avatar-stack { display: inline-flex; align-items: center; }
.ui-avatar-stack .ui-avatar { box-shadow: 0 0 0 2px var(--surface); }
.ui-avatar-stack .ui-avatar + .ui-avatar { margin-left: calc(var(--_size) * -.25); } /* ≤25% overlap keeps initials readable */
.ui-avatar--more { --_bg: var(--surface-3); --_fg: var(--ink-2); font-size: max(var(--fs-label-s), calc(var(--_size) * .34)); font-weight: var(--fw-bold); }

/* ---------- 9. Cards ------------------------------------------------ */
/* .ui-card (+ --interactive when the whole card is a link/button, --flat, --pad-lg, --tint, --pad-0) */
.ui-card { --_pad: var(--sp-5); position: relative; display: block; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-1); padding: var(--_pad); min-width: 0; }
.ui-card--flat { box-shadow: none; background: var(--surface-2); }
.ui-card--tint { box-shadow: none; background: var(--primary-soft); border-color: transparent; }
.ui-card--pad-lg { --_pad: var(--sp-7); }
.ui-card--pad-0 { --_pad: 0px; overflow: hidden; }
.ui-card--interactive { cursor: pointer; transition: box-shadow var(--dur-2) var(--ease-standard), transform var(--dur-2) var(--ease-standard), border-color var(--dur-2); text-align: left; width: 100%; }
@media (hover: hover) { .ui-card--interactive:hover { box-shadow: var(--sh-2); transform: translateY(-1px); border-color: var(--line-strong); } }
.ui-card--interactive:active { transform: scale(.992); }
.ui-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.ui-card__title { font-size: var(--fs-title); font-weight: var(--fw-semibold); letter-spacing: var(--ls-tight); line-height: var(--lh-title); }
.ui-card__text { font-size: var(--fs-body-s); color: var(--muted); line-height: var(--lh-body-s); }
.ui-card__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); margin-top: var(--sp-4); padding-top: var(--sp-3); border-top: 1px solid var(--line); }
@media (max-width: 767px) { .ui-card { --_pad: 18px; } .ui-card--pad-lg { --_pad: 22px; } .ui-card--pad-0 { --_pad: 0px; } }

/* Hero — the calm v2 "săptămâna în 20 de secunde" block. */
.ui-hero { background: var(--hero-bg); border: 1px solid var(--hero-line); border-radius: var(--r-lg); overflow: hidden; }
.ui-hero__main { padding: var(--sp-6) var(--sp-5) var(--sp-5); }
.ui-hero__eyebrow { color: var(--hero-ink); }
.ui-hero__title { margin: 14px 0 12px; font-family: var(--font-display); font-weight: var(--fw-regular); font-size: var(--fs-display-l); line-height: var(--lh-display-l); letter-spacing: var(--ls-display); text-wrap: balance; }
.ui-hero__text { color: var(--hero-ink); font-size: var(--fs-body); line-height: 1.6; max-width: 58ch; }
.ui-hero__meta { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); }
.ui-hero__pill { display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 3px 11px; border-radius: var(--r-pill); background: var(--surface-glass); color: var(--hero-ink); font-size: var(--fs-caption); font-weight: var(--fw-semibold); }
.ui-hero__pill .ui-i { width: 14px; height: 14px; }
.ui-hero__strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); gap: 0; background: var(--hero-bg-2); border-top: 1px solid var(--hero-line); padding: var(--sp-4) var(--sp-5); }
.ui-hero__stat { padding: 0 var(--sp-3); border-left: 1px solid var(--hero-line); }
.ui-hero__stat:first-child { border-left: 0; padding-left: 0; }
.ui-hero__stat b { display: block; font-family: var(--font-display); font-weight: var(--fw-regular); font-size: var(--fs-display-s); line-height: 1.2; color: var(--ink); }
.ui-hero__stat span { font-size: var(--fs-caption); color: var(--hero-ink); line-height: 1.35; display: block; }
@media (min-width: 768px) { .ui-hero__main { padding: var(--sp-8) var(--sp-8) var(--sp-7); } .ui-hero__strip { padding: var(--sp-5) var(--sp-8); } .ui-hero__title { font-size: var(--fs-display-xl); line-height: var(--lh-display-xl); } .ui-hero__text { font-size: var(--fs-title); } }

/* Subject card — v2's tinted code band is back.
   <a class="ui-card ui-card--interactive ui-subject ui-sub--clr">
     <span class="ui-subject__code">CLR</span><span class="ui-subject__go">{icon chevron-right}</span>
     <span class="ui-subject__title">Română</span><span class="ui-subject__text">…</span></a> */
.ui-subject { display: flex; flex-direction: column; gap: 6px; padding-top: 0; }
.ui-subject__code {
  display: flex; align-items: center; min-height: 40px; margin: -1px calc(var(--_pad) * -1 - 1px) 10px; padding: 0 calc(var(--_pad) + 1px);
  border-radius: var(--r-lg) var(--r-lg) 0 0; background: var(--_bg); color: var(--_fg);
  font-size: var(--fs-label); font-weight: var(--fw-bold); letter-spacing: .06em;
}
.ui-subject__title { font-size: var(--fs-title); line-height: var(--lh-title); font-weight: var(--fw-semibold); letter-spacing: var(--ls-tight); }
.ui-subject__text { font-size: var(--fs-body-s); color: var(--muted); line-height: var(--lh-body-s); }
.ui-subject__go { position: absolute; top: 0; right: calc(var(--_pad) - 4px); display: grid; place-items: center; height: 40px; color: var(--_fg); transition: transform var(--dur-2) var(--ease-standard); }
.ui-subject:hover .ui-subject__go { transform: translateX(2px); }

/* Event card: date block + details. Put .ui-sub--* on it for colour. */
.ui-event { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--sp-4); align-items: start; }
.ui-event__date { display: grid; place-items: center; align-content: center; width: 54px; min-height: 60px; padding: 6px 0; border-radius: var(--r-md); background: var(--_bg, var(--primary-soft)); color: var(--_fg, var(--on-primary-soft)); line-height: 1; }
.ui-event__day { font-size: var(--fs-label-s); font-weight: var(--fw-bold); letter-spacing: .08em; text-transform: uppercase; }
.ui-event__num { font-family: var(--font-display); font-size: var(--fs-display-s); margin-top: 4px; font-weight: var(--fw-medium); }
.ui-event__body { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr); gap: 6px; }
.ui-event__title { font-size: var(--fs-title); font-weight: var(--fw-semibold); letter-spacing: var(--ls-tight); line-height: 1.3; }
.ui-event__meta { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: var(--fs-body-s); color: var(--muted); }
.ui-event__meta > span { display: inline-flex; align-items: center; gap: 5px; }
.ui-event__meta .ui-i { width: 15px; height: 15px; }
.ui-event__foot { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; align-items: center; }

/* Photo mosaic (album preview): ALWAYS 3 columns, 1 --feature (2×2) + exactly 5
   tiles = 9 cells, no hole; "+N" goes on the LAST tile.
   <div class="ui-photos"><button class="ui-photo ui-photo--feature">…</button> ×5 …
     <button class="ui-photo" aria-label="Încă 12 fotografii">…<span class="ui-photo__more">+12</span></button></div>
   Galleries without a feature: .ui-photos--wide (3 / 4 / 6 columns). */
.ui-photos { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-flow: dense; gap: 3px; border-radius: var(--r-md); overflow: hidden; }
@media (min-width: 768px) { .ui-photos--wide { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 1100px) { .ui-photos--wide { grid-template-columns: repeat(6, 1fr); } }
.ui-photo { position: relative; aspect-ratio: 1; overflow: hidden; background: var(--surface-3); display: block; width: 100%; }
.ui-photo img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-3) var(--ease-standard); }
.ui-photo:hover img { transform: scale(1.03); }
.ui-photo--feature { grid-column: span 2; grid-row: span 2; }
.ui-photo__more { position: absolute; inset: 0; display: grid; place-items: center; background: var(--scrim-media); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); color: var(--on-media); font-size: var(--fs-title-l); font-weight: var(--fw-semibold); }
.ui-photo__check { position: absolute; top: 6px; right: 6px; width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--on-media); background: var(--scrim-media); }
.ui-photo.is-selected .ui-photo__check { background: var(--primary); }
.ui-photo.is-selected img { transform: scale(.9); border-radius: 8px; }
/* Placeholder art when no image yet (theme-aware). */
.ui-photo__ph { position: absolute; inset: 0; background: linear-gradient(145deg, var(--_bg, var(--primary-soft)), var(--surface-3)); }
.ui-photo__ph::after { content: ""; position: absolute; left: 18%; right: 18%; bottom: 0; height: 42%; border-radius: 50% 50% 0 0; background: color-mix(in srgb, var(--_fg, var(--primary)) 18%, transparent); }
.ui-photo__ph::before { content: ""; position: absolute; right: 22%; top: 20%; width: 18%; aspect-ratio: 1; border-radius: 50%; background: color-mix(in srgb, var(--_fg, var(--accent)) 28%, transparent); }

/* ---------- 10. Lists & rows --------------------------------------- */
/* <div class="ui-list"> <a class="ui-row" href="#">
      <span class="ui-row__lead">{icon}</span>
      <span class="ui-row__body"><span class="ui-row__title">…</span><span class="ui-row__sub">…</span></span>
      <span class="ui-row__trail"><span class="ui-row__meta">09:30</span>{icon chevron-right}</span></a></div>
   Unread: .is-unread on the row AND <span class="ui-sr-only">necitit, </span> first in the title. */
.ui-list { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-1); overflow: hidden; }
.ui-list--plain { background: transparent; border: 0; border-radius: 0; box-shadow: none; overflow: visible; }
.ui-row {
  position: relative; display: flex; align-items: center; gap: var(--sp-3); width: 100%; min-height: 60px; padding: 12px var(--sp-4);
  text-align: left; color: inherit; background: transparent; transition: background-color var(--dur-1);
}
.ui-list--plain .ui-row { padding-inline: 0; }
.ui-row + .ui-row::before { content: ""; position: absolute; top: 0; right: 0; left: calc(var(--sp-4) + 52px); height: 1px; background: var(--line); }
.ui-list--plain .ui-row + .ui-row::before { left: 52px; }
.ui-row--no-lead + .ui-row--no-lead::before { left: var(--sp-4); }
a.ui-row:hover, button.ui-row:hover, label.ui-row:hover { background: var(--surface-2); }
a.ui-row:active, button.ui-row:active { background: var(--surface-3); }
.ui-row__lead { display: grid; place-items: center; width: 40px; height: 40px; flex-shrink: 0; border-radius: 12px; background: var(--_bg, var(--surface-3)); color: var(--_fg, var(--ink-2)); }
.ui-row__lead--plain { background: transparent; }
.ui-row__body { flex: 1; min-width: 0; display: grid; gap: 2px; }
.ui-row__title { font-size: var(--fs-body); font-weight: var(--fw-semibold); letter-spacing: -.005em; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-row__title--wrap { white-space: normal; }
.ui-row__sub { font-size: var(--fs-body-s); color: var(--muted); line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ui-row__trail { display: flex; align-items: center; gap: 6px; flex-shrink: 0; color: var(--subtle); }
.ui-row__meta { font-size: var(--fs-caption); color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.ui-row.is-unread .ui-row__title::after { content: ""; display: inline-block; width: 8px; height: 8px; margin-left: 8px; vertical-align: middle; border-radius: 50%; background: var(--primary-ink); }

/* Section header: eyebrow + serif title + optional action (text baselines aligned). */
.ui-section-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-3); margin: var(--sp-7) 0 var(--sp-3); }
.ui-section-head:first-child { margin-top: 0; }
.ui-section-head__text { display: grid; gap: 6px; min-width: 0; }
.ui-section-head__title { font-family: var(--font-display); font-weight: var(--fw-regular); font-size: var(--fs-display-s); line-height: var(--lh-display-s); letter-spacing: var(--ls-display); }
.ui-section-head__action { display: inline-flex; align-items: center; gap: 4px; min-height: var(--touch); margin-bottom: -11px; padding: 0 4px; font-size: var(--fs-button); font-weight: var(--fw-semibold); color: var(--primary-ink); white-space: nowrap; }
@supports (align-items: last baseline) {
  .ui-section-head { align-items: last baseline; }
  .ui-section-head__action { margin-bottom: 0; }
}
.ui-section-head__action .ui-i { width: 16px; height: 16px; transition: transform var(--dur-2) var(--ease-standard); }
.ui-section-head__action:hover .ui-i { transform: translateX(2px); }

/* Key–value rows. Per-row audience: put a chip in <span class="ui-kv__aud"> at the end
   of the <dd> (e.g. Alergii visible to staff while the rest of the card is private). */
.ui-kv { display: grid; }
.ui-kv__row { display: grid; grid-template-columns: minmax(96px, 36%) minmax(0, 1fr); gap: var(--sp-3); padding: 12px 0; border-top: 1px solid var(--line); font-size: var(--fs-body-s); }
.ui-kv__row:first-child { border-top: 0; }
.ui-kv__row dt { color: var(--muted); }
.ui-kv__row dd { display: flex; align-items: flex-start; gap: var(--sp-2); color: var(--ink); font-weight: var(--fw-medium); min-width: 0; overflow-wrap: anywhere; }
.ui-kv__aud { margin-left: auto; flex-shrink: 0; margin-top: -3px; }

/* ---------- 11. Tabs ----------------------------------------------- */
/* <div class="ui-tabs" role="tablist" aria-label="…"><button class="ui-tab" role="tab" aria-selected="true">Rezumat</button>…
   Scrolls horizontally with snap; App.ui.bindSegmented() adds edge fades
   (.is-fade-start / .is-fade-end) and keeps the selected tab in view. */
.ui-tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity; scroll-padding-inline: 24px; }
.ui-tabs::-webkit-scrollbar { display: none; }
.ui-tabs.is-fade-end { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent); }
.ui-tabs.is-fade-start { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 40px), transparent); }
.ui-tabs.is-fade-start.is-fade-end { -webkit-mask-image: linear-gradient(to right, transparent, #000 40px, #000 calc(100% - 40px), transparent); mask-image: linear-gradient(to right, transparent, #000 40px, #000 calc(100% - 40px), transparent); }
.ui-tab {
  position: relative; display: inline-flex; align-items: center; gap: 7px; flex-shrink: 0; min-height: 46px; padding: 0 14px; scroll-snap-align: start;
  font-size: var(--fs-button); font-weight: var(--fw-medium); color: var(--muted); white-space: nowrap; transition: color var(--dur-1);
}
.ui-tab .ui-i { width: 17px; height: 17px; }
.ui-tab:hover { color: var(--ink); }
.ui-tab[aria-selected="true"] { color: var(--ink); font-weight: var(--fw-semibold); }
.ui-tab::after { content: ""; position: absolute; left: 12px; right: 12px; bottom: -1px; height: 3px; border-radius: 3px 3px 0 0; background: var(--primary-ink); transform: scaleX(0); transition: transform var(--dur-2) var(--ease-standard); }
.ui-tab[aria-selected="true"]::after { transform: scaleX(1); }
@media (max-width: 399px) { .ui-tab { padding: 0 10px; gap: 6px; } .ui-tab::after { left: 8px; right: 8px; } }

/* ---------- 12. Callout, tooltip ----------------------------------- */
/* <div class="ui-callout ui-callout--info">{icon}<div class="ui-callout__body"><p class="ui-callout__title">…</p>…</div></div>
   --private: every "who can see this" explanation (lock in an inverted disc,
   matching the "Doar noi" chip). --danger ONLY for errors / destructive states. */
.ui-callout { --_fg: var(--info-ink); --_bg: var(--info-soft); display: flex; gap: var(--sp-3); align-items: flex-start; padding: 14px 16px; border-radius: var(--r-md); background: var(--_bg); color: var(--ink); font-size: var(--fs-body-s); line-height: var(--lh-body-s); }
.ui-callout > .ui-i { color: var(--_fg); margin-top: 1px; }
.ui-callout__title { font-weight: var(--fw-semibold); color: var(--_fg); margin-bottom: 2px; font-size: var(--fs-body-s); }
.ui-callout__body { flex: 1; min-width: 0; }
.ui-callout__actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-3); flex-wrap: wrap; }
.ui-callout--info    { --_fg: var(--info-ink);    --_bg: var(--info-soft); }
.ui-callout--success { --_fg: var(--success-ink); --_bg: var(--success-soft); }
.ui-callout--warning { --_fg: var(--warning-ink); --_bg: var(--warning-soft); }
.ui-callout--danger  { --_fg: var(--danger-ink);  --_bg: var(--danger-soft); }
.ui-callout--ai      { --_fg: var(--ai-ink);      --_bg: var(--ai-soft); }
.ui-callout--neutral { --_fg: var(--muted); --_bg: var(--surface-2); border: 1px solid var(--line); }
.ui-callout--private { --_fg: var(--ink); --_bg: var(--surface-2); border: 1px solid var(--line-strong); }
.ui-callout--private > .ui-i { box-sizing: content-box; width: 14px; height: 14px; padding: 5px; margin-top: -2px; border-radius: 50%; background: var(--aud-private-bg); color: var(--aud-private-fg); stroke-width: 2; }

/* CSS tooltip: <button data-tooltip="Copiază link">…</button> (hover devices only).
   Uses ::before (do not put it on elements that use ::before themselves).
   Zero-specificity positioning (never overrides fixed/absolute components);
   hoverable (transparent border bridges the gap); Esc hides it (ui.js). */
@media (hover: hover) {
  :where([data-tooltip]) { position: relative; }
  [data-tooltip]::before {
    content: attr(data-tooltip); position: absolute; left: 50%; bottom: 100%; z-index: var(--z-tooltip);
    width: max-content; max-width: min(240px, 90vw); padding: 6px 10px; border-bottom: 8px solid transparent; background-clip: padding-box;
    border-radius: 8px 8px 8px 8px / 8px 8px 16px 16px; background-color: var(--inverse-surface); color: var(--on-inverse-surface);
    font-size: var(--fs-caption); font-weight: var(--fw-medium); line-height: 1.35; letter-spacing: 0; text-transform: none; white-space: normal; text-align: center;
    transform: translate(-50%, 0); pointer-events: none;
    display: none; /* not rendered until shown: a hidden tooltip near the right edge must not widen the page */
  }
  [data-tooltip]:hover::before, [data-tooltip]:focus-visible::before { display: block; pointer-events: auto; animation: ui-tip-in var(--dur-2) var(--ease-standard) 350ms both; }
  @keyframes ui-tip-in { from { opacity: 0; transform: translate(-50%, 4px); } to { opacity: 1; transform: translate(-50%, 0); } }
  [data-tooltip-pos="bottom"]::before { bottom: auto; top: 100%; border-bottom: 0; border-top: 8px solid transparent; border-radius: 8px 8px 8px 8px / 16px 16px 8px 8px; }
  .ui-tips-hidden [data-tooltip]::before { display: none !important; }
}

/* ---------- 13. Overlays: sheet / modal / side panel --------------- */
/* Built by App.ui.openSheet(). Mobile: bottom sheet. ≥768: centred modal.
   ≥1100 with {side:true}: right side panel. --kb = on-screen keyboard height
   (set by ui.js from visualViewport). */
.ui-overlay { position: fixed; inset: 0; z-index: var(--z-overlay); background: var(--scrim); opacity: 0; transition: opacity var(--dur-3) var(--ease-standard); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.ui-overlay.is-open { opacity: 1; }
.ui-sheet {
  position: fixed; left: 0; right: 0; bottom: var(--kb, 0px); z-index: var(--z-sheet);
  display: flex; flex-direction: column; max-height: calc(100dvh - var(--safe-top) - 24px - var(--kb, 0px));
  background: var(--surface); color: var(--ink); border-radius: var(--r-xl) var(--r-xl) 0 0; box-shadow: var(--sh-4);
  transform: translateY(104%); transition: transform var(--dur-3) var(--ease-decelerate); outline: none;
}
.ui-sheet.is-open { transform: translateY(0); }
.ui-sheet.is-closing { transition: transform var(--dur-2) var(--ease-accelerate); }
/* Handle: 5px pill, 44px-tall drag area (centre half only, so the close button stays clickable). */
.ui-sheet__handle { position: relative; align-self: stretch; height: 20px; flex-shrink: 0; cursor: grab; touch-action: none; z-index: 1; }
.ui-sheet__handle::before { content: ""; position: absolute; left: 50%; top: 8px; width: 40px; height: 5px; margin-left: -20px; border-radius: var(--r-pill); background: var(--line-strong); }
.ui-sheet__handle::after { content: ""; position: absolute; left: 25%; right: 25%; top: 0; height: 44px; }
.ui-sheet__head { display: flex; align-items: flex-start; gap: var(--sp-3); padding: 2px var(--sp-3) var(--sp-2) var(--sp-5); flex-shrink: 0; }
.ui-sheet__heading { flex: 1; min-width: 0; padding-top: 6px; }
.ui-sheet__title { font-family: var(--font-display); font-size: var(--fs-display-s); line-height: 1.2; letter-spacing: var(--ls-display); font-weight: var(--fw-regular); }
.ui-sheet__sub { font-size: var(--fs-body-s); color: var(--muted); margin-top: 3px; line-height: 1.4; }
.ui-sheet__body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: var(--sp-2) var(--sp-5) var(--sp-5); }
.ui-sheet__body:last-child { padding-bottom: calc(var(--sp-5) + var(--safe-bottom)); }
.ui-sheet__foot { display: flex; gap: var(--sp-2); padding: var(--sp-3) var(--sp-5) calc(var(--sp-3) + var(--safe-bottom)); border-top: 1px solid var(--line); flex-shrink: 0; background: var(--surface); }
.ui-sheet__foot .ui-btn { flex: 1; }
@media (min-width: 768px) {
  .ui-sheet {
    left: 50%; top: 50%; right: auto; bottom: auto; width: min(560px, calc(100vw - 48px)); max-height: min(760px, calc(100dvh - 64px));
    border-radius: var(--r-lg); transform: translate(-50%, -47%) scale(.97); opacity: 0;
    transition: transform var(--dur-3) var(--ease-decelerate), opacity var(--dur-2) var(--ease-standard);
  }
  .ui-sheet.is-open { transform: translate(-50%, -50%) scale(1); opacity: 1; }
  .ui-sheet.is-closing { transition: transform var(--dur-2) var(--ease-accelerate), opacity var(--dur-2) var(--ease-standard); }
  .ui-sheet--wide { width: min(820px, calc(100vw - 48px)); }
  .ui-sheet__handle { display: none; }
  .ui-sheet__head { padding: var(--sp-5) var(--sp-4) var(--sp-2) var(--sp-6); }
  .ui-sheet__body { padding: var(--sp-2) var(--sp-6) var(--sp-6); }
  .ui-sheet__foot { justify-content: flex-end; padding: var(--sp-4) var(--sp-6); border-radius: 0 0 var(--r-lg) var(--r-lg); }
  .ui-sheet__foot .ui-btn { flex: 0 0 auto; }
}
@media (min-width: 1100px) {
  .ui-sheet--side {
    left: auto; top: 12px; right: 12px; bottom: 12px; width: min(460px, calc(100vw - 24px)); max-height: none;
    transform: translateX(calc(100% + 24px)); opacity: 1;
  }
  .ui-sheet--side.is-open { transform: translateX(0); }
  .ui-sheet--side.is-closing { transition: transform var(--dur-2) var(--ease-accelerate); }
}

/* Toast (App.ui.toast) — inverse surface (Flutter SnackBar: inverseSurface /
   onInverseSurface / inversePrimary). The region exists from page load. */
.ui-toasts { position: fixed; left: 0; right: 0; bottom: calc(var(--tabbar-h) + var(--safe-bottom) + var(--sp-3)); z-index: var(--z-toast); display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); padding: 0 var(--gutter); pointer-events: none; }
@media (min-width: 1100px) { .ui-toasts { bottom: var(--sp-6); } }
.ui-toast {
  pointer-events: auto; display: flex; align-items: center; gap: var(--sp-3); max-width: min(480px, 100%); min-height: 48px; padding: 6px 6px 6px 16px;
  border-radius: var(--r-md); background: var(--inverse-surface); color: var(--on-inverse-surface); box-shadow: var(--sh-3); font-size: var(--fs-body-s); font-weight: var(--fw-medium);
  animation: ui-toast-in var(--dur-3) var(--ease-decelerate);
}
.ui-toast > .ui-i { color: var(--inverse-primary); }
.ui-toast__msg { flex: 1; min-width: 0; padding: 6px 6px 6px 0; }
.ui-toast__action { min-height: var(--touch); padding: 0 12px; border-radius: 10px; font-weight: var(--fw-bold); font-size: var(--fs-button); color: var(--inverse-primary); }
.ui-toast__action:hover, .ui-toast__close:hover { background: color-mix(in srgb, var(--on-inverse-surface) 10%, transparent); }
.ui-toast__close { display: grid; place-items: center; width: var(--touch); height: var(--touch); border-radius: 50%; color: var(--on-inverse-surface); }
.ui-toast.is-leaving { animation: ui-toast-out var(--dur-2) var(--ease-accelerate) forwards; }
@keyframes ui-toast-in { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes ui-toast-out { to { opacity: 0; transform: translateY(8px) scale(.98); } }

/* ---------- 14. Empty, skeleton, progress, dropzone ---------------- */
/* Empty state: honest copy, one action. (App.ui.emptyState) */
.ui-empty { display: grid; justify-items: center; text-align: center; gap: var(--sp-2); padding: var(--sp-8) var(--sp-5); }
.ui-empty__art { position: relative; isolation: isolate; display: grid; place-items: center; width: 88px; height: 88px; margin-bottom: var(--sp-3); border-radius: 28px; background: var(--primary-soft); color: var(--primary-ink); transform: rotate(-4deg); }
.ui-empty__art::before { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--accent-soft); transform: rotate(10deg) translate(6px, 4px); z-index: -1; }
.ui-empty__art .ui-i { width: 36px; height: 36px; stroke-width: 1.5; transform: rotate(4deg); }
.ui-empty__title { font-family: var(--font-display); font-size: var(--fs-display-s); line-height: 1.2; font-weight: var(--fw-regular); letter-spacing: var(--ls-display); }
.ui-empty__text { max-width: 38ch; color: var(--muted); font-size: var(--fs-body-s); }
.ui-empty__action { margin-top: var(--sp-3); }

.ui-skel { display: block; background: var(--surface-3); border-radius: var(--r-xs); position: relative; overflow: hidden; }
.ui-skel::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, var(--shimmer), transparent); animation: ui-shimmer 1.4s infinite; }
.ui-skel--text { height: 12px; margin: 6px 0; }
.ui-skel--title { height: 20px; width: 60%; margin: 4px 0 10px; }
.ui-skel--circle { border-radius: 50%; }
@keyframes ui-shimmer { to { transform: translateX(100%); } }

/* <div class="ui-progress" role="progressbar" aria-valuenow="64" aria-valuemin="0" aria-valuemax="100" style="--value:64"><span class="ui-progress__bar"></span></div> */
.ui-progress { position: relative; height: 6px; border-radius: var(--r-pill); background: var(--surface-3); overflow: hidden; }
.ui-progress__bar { position: absolute; inset: 0 auto 0 0; width: calc(var(--value, 0) * 1%); border-radius: inherit; background: var(--primary); transition: width var(--dur-3) var(--ease-standard); }
.ui-progress--ai .ui-progress__bar { background: linear-gradient(90deg, var(--ai), var(--primary)); }
.ui-progress--indeterminate .ui-progress__bar { width: 35%; animation: ui-indet 1.2s var(--ease-standard) infinite; }
@keyframes ui-indet { from { left: -35%; } to { left: 100%; } }
/* Upload item row. Icon colour: neutral by default, or put .ui-sub--* / --_fg/--_bg on it. */
.ui-upload { display: grid; grid-template-columns: auto 1fr auto; gap: 6px var(--sp-3); align-items: center; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface); }
.ui-upload__icon { grid-row: span 2; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 11px; background: var(--_bg, var(--surface-3)); color: var(--_fg, var(--ink-2)); }
.ui-upload__name { font-size: var(--fs-body-s); font-weight: var(--fw-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-upload__meta { font-size: var(--fs-caption); color: var(--muted); white-space: nowrap; }
.ui-upload .ui-progress { grid-column: 2 / 4; }

/* Dropzone: <label class="ui-drop"><input type="file" class="ui-sr-only">…</label>; .is-over while dragging.
   Title copy per input: <span class="ui-only-fine">Trage aici…</span><span class="ui-only-coarse">Alege…</span> */
.ui-drop {
  display: grid; justify-items: center; text-align: center; gap: 6px; padding: var(--sp-7) var(--sp-5); cursor: pointer;
  border: 1.5px dashed var(--control-border); border-radius: var(--r-lg); background: var(--surface-2);
  transition: border-color var(--dur-1), background-color var(--dur-1), transform var(--dur-2) var(--ease-standard);
}
.ui-drop:hover, .ui-drop.is-over { border-color: var(--primary-ink); background: var(--primary-soft); }
.ui-drop.is-over { transform: scale(1.01); }
.ui-drop:has(input:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.ui-drop__icon { display: grid; place-items: center; width: 52px; height: 52px; margin-bottom: 6px; border-radius: 16px; background: var(--surface); color: var(--primary-ink); box-shadow: var(--sh-2); }
.ui-drop__title { font-weight: var(--fw-semibold); font-size: var(--fs-body); }
.ui-drop__text { font-size: var(--fs-body-s); color: var(--muted); max-width: 40ch; }
.ui-drop__sources { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; margin-top: var(--sp-3); }
@media (pointer: coarse) { .ui-drop__sources { display: grid; grid-template-columns: repeat(2, minmax(0, max-content)); } }

/* ---------- 15. Stepper & timeline -------------------------------- */
/* <ol class="ui-steps"><li class="ui-step is-done"><span class="ui-step__dot">{check}</span><span class="ui-step__label">Primit</span></li>
   … <li class="ui-step is-current" aria-current="step">… */
.ui-steps { display: flex; align-items: flex-start; counter-reset: step; }
.ui-step { position: relative; flex: 1; display: grid; justify-items: center; gap: 6px; text-align: center; font-size: var(--fs-caption); color: var(--muted); counter-increment: step; min-width: 0; }
.ui-step::before { content: ""; position: absolute; top: 13px; right: 50%; width: 100%; height: 2px; background: var(--line-strong); z-index: 0; }
.ui-step:first-child::before { display: none; }
.ui-step.is-done::before, .ui-step.is-current::before { background: var(--primary); }
.ui-step__dot { position: relative; z-index: 1; display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--surface); border: 2px solid var(--control-border); font-size: var(--fs-caption); font-weight: var(--fw-bold); color: var(--muted); }
.ui-step__dot:empty::after { content: counter(step); }
.ui-step__dot .ui-i { width: 14px; height: 14px; stroke-width: 2.4; }
.ui-step.is-done .ui-step__dot { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.ui-step.is-current .ui-step__dot { border-color: var(--primary-ink); color: var(--primary-ink); box-shadow: 0 0 0 4px var(--primary-soft-2); }
.ui-step.is-current .ui-step__label { color: var(--ink); font-weight: var(--fw-semibold); }
.ui-step__label { line-height: 1.25; padding: 0 2px; overflow-wrap: anywhere; }

/* <ol class="ui-timeline"><li class="ui-tl"><span class="ui-tl__dot">{icon}</span><div class="ui-tl__body">…</div></li> */
.ui-timeline { display: grid; }
.ui-tl { position: relative; display: grid; grid-template-columns: 32px 1fr; gap: var(--sp-3); padding-bottom: var(--sp-5); }
.ui-tl::before { content: ""; position: absolute; left: 15.5px; top: 34px; bottom: 2px; width: 1px; background: var(--line-strong); }
.ui-tl:last-child { padding-bottom: 0; }
.ui-tl:last-child::before { display: none; }
.ui-tl__dot { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; background: var(--_bg, var(--surface-3)); color: var(--_fg, var(--ink-2)); }
.ui-tl__dot .ui-i { width: 15px; height: 15px; }
.ui-tl__body { min-width: 0; padding-top: 5px; }
.ui-tl__title { font-size: var(--fs-body-s); font-weight: var(--fw-semibold); line-height: 1.4; }
.ui-tl__meta { font-size: var(--fs-caption); color: var(--muted); margin-top: 2px; }
.ui-tl__text { font-size: var(--fs-body-s); color: var(--ink-2); margin-top: 6px; }

/* ---------- 16. Calendar primitives -------------------------------- */
/* Week/day view. Events are positioned by minutes since midnight:
   <div class="ui-cal" style="--days:5; --start:480; --end:900; --line-at:525">
     <div class="ui-cal__head"><div></div><div class="ui-cal__dayhead is-today"><span>Vin</span><b>25</b></div>…</div>
     <div class="ui-cal__allday"><div>Toată ziua</div><div><span class="ui-cal-allday ui-sub--mm">…</span></div>…</div>
     <div class="ui-cal__grid"><div class="ui-cal__times"><span style="--at:525">08:45</span>…</div>
       <div class="ui-cal__col"><button class="ui-cal-ev ui-sub--clr" style="--from:525;--to:570" aria-label="luni 21 sept., 08:45–09:30, Comunicare în limba română">
         <span class="ui-cal-ev__time">08:45–09:30</span><span class="ui-cal-ev__code">CLR</span><span class="ui-cal-ev__title">Comunicare…</span></button>…
   --line-at: minute of ONE gridline (default --start); lines repeat every hour
   from there, so schools starting at :45 get lines at period starts.
   Label the times you draw lines at (always render the first label).
   PHONES: prefer --days:1 with .ui-daystrip above it (or --days:3).
   A 5-day .ui-cal--week on phones shows subject CODES (add __code) and keeps
   time/title for screen readers only. */
.ui-cal { --hour: 56px; --min: calc(var(--hour) / 60); --days: 5; --start: 480; --end: 1080; --line-at: var(--start); --gutter-w: 52px;
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); overflow: hidden; box-shadow: var(--sh-1); }
.ui-cal__head, .ui-cal__allday, .ui-cal__grid { display: grid; grid-template-columns: var(--gutter-w) repeat(var(--days), minmax(0, 1fr)); }
.ui-cal__head { background: var(--surface-2); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: var(--z-raised); }
.ui-cal__dayhead { display: grid; justify-items: center; gap: 2px; padding: 10px 4px; font-size: var(--fs-caption); color: var(--muted); font-weight: var(--fw-medium); border-left: 1px solid var(--line); }
.ui-cal__dayhead b { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 50%; font-family: var(--font-display); font-size: var(--fs-title-l); font-weight: var(--fw-regular); color: var(--ink); }
.ui-cal__dayhead.is-today { color: var(--primary-ink); font-weight: var(--fw-bold); }
.ui-cal__dayhead.is-today b { background: var(--primary); color: var(--on-primary); }
.ui-cal__dayhead.is-weekend { background: var(--paper-2); }
.ui-cal__allday { border-bottom: 1px solid var(--line); min-height: 34px; }
.ui-cal__allday > * { border-left: 1px solid var(--line); padding: 4px; display: grid; gap: 3px; align-content: start; min-width: 0; }
.ui-cal__allday > :first-child { border-left: 0; font-size: var(--fs-label-s); color: var(--muted); padding: 8px 6px; line-height: 1.2; }
.ui-cal-allday { padding: 3px 8px; border-radius: 6px; background: var(--_bg, var(--surface-3)); color: var(--_fg, var(--ink-2)); font-size: var(--fs-label-s); line-height: 1.25; font-weight: var(--fw-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-cal__grid { position: relative; height: calc((var(--end) - var(--start)) * var(--min)); }
.ui-cal__times { position: relative; }
.ui-cal__times span { position: absolute; right: 8px; top: max(2px, calc((var(--at) - var(--start)) * var(--min) - 8px)); font-size: var(--fs-label-s); color: var(--muted); font-variant-numeric: tabular-nums; }
.ui-cal__col {
  position: relative; border-left: 1px solid var(--line);
  background-image: linear-gradient(to bottom, var(--line) 0 1px, transparent 1px);
  background-size: 100% var(--hour);
  background-position: 0 calc((var(--line-at) - var(--start)) * var(--min));
}
.ui-cal__col.is-today { background-color: color-mix(in srgb, var(--primary-soft) 45%, transparent); }
.ui-cal__col.is-weekend { background-color: var(--paper-2); }
.ui-cal__now { position: absolute; left: 0; right: 0; top: calc((var(--at) - var(--start)) * var(--min)); height: 2px; background: var(--danger); z-index: 2; }
.ui-cal__now::before { content: ""; position: absolute; left: -5px; top: -4px; width: 10px; height: 10px; border-radius: 50%; background: var(--danger); }
.ui-cal-ev {
  position: absolute; left: 3px; right: 3px; top: calc((var(--from) - var(--start)) * var(--min) + 1px); height: calc((var(--to) - var(--from)) * var(--min) - 3px);
  padding: 4px 7px; overflow: hidden; border-radius: 8px; border-left: 3px solid var(--_fg, var(--control-border));
  background-color: var(--_bg, var(--surface-3)); color: var(--_fg, var(--ink-2)); /* no subject = neutral (lunch, breaks) */ font-size: var(--fs-caption); line-height: 1.25; text-align: left;
  transition: box-shadow var(--dur-1), transform var(--dur-1);
}
button.ui-cal-ev:hover, a.ui-cal-ev:hover { box-shadow: var(--sh-2); z-index: 3; }
.ui-cal-ev__time { display: block; font-size: var(--fs-label-s); font-weight: var(--fw-medium); font-variant-numeric: tabular-nums; }
.ui-cal-ev__title { display: block; font-weight: var(--fw-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-cal-ev__code { display: none; font-size: var(--fs-label-s); font-weight: var(--fw-bold); letter-spacing: .03em; }
.ui-cal-ev .ui-i { display: inline-block; width: 12px; height: 12px; margin-right: 3px; vertical-align: -2px; stroke-width: 2; }
.ui-cal-ev--wrap .ui-cal-ev__title { white-space: normal; } /* long events: allow wrapping */
.ui-cal-ev--optional { border: 1px dashed var(--_fg, var(--primary-ink)); border-left: 3px dashed var(--_fg, var(--primary-ink)); background-color: var(--surface); }
.ui-cal-ev--half-l { right: 50%; } .ui-cal-ev--half-r { left: 50%; }
/* Private: hatch + lock icon (put icon('lock') + <span class="ui-sr-only">privat</span> in the title). */
.ui-cal-ev--private { background-image: repeating-linear-gradient(135deg, transparent 0 5px, color-mix(in srgb, var(--_fg, var(--primary-ink)) 16%, transparent) 5px 10px); }
@media (max-width: 767px) {
  .ui-cal { --gutter-w: 44px; }
  .ui-cal__dayhead b { width: 30px; height: 30px; font-size: var(--fs-title); }
  .ui-cal__times span { right: 5px; }
  .ui-cal-ev { left: 2px; right: 2px; padding: 3px 4px; font-size: var(--fs-label-s); border-left-width: 2px; border-radius: 6px; }
  .ui-cal--week .ui-cal-ev__time,
  .ui-cal--week .ui-cal-ev:has(.ui-cal-ev__code) .ui-cal-ev__title { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
  .ui-cal--week .ui-cal-ev__code { display: block; }
  .ui-cal--week .ui-cal-ev__title { white-space: normal; overflow-wrap: normal; hyphens: auto; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.2; }
  .ui-cal--week .ui-cal-allday { padding: 2px 4px; white-space: normal; hyphens: auto; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
}

/* Day strip (phones): pick a day above a --days:1 view.
   <div class="ui-daystrip" role="group" aria-label="Săptămâna 21–27 sept.">
     <button class="ui-daystrip__day" aria-pressed="true" aria-current="date"><span>Vin</span><b>25</b></button>… */
.ui-daystrip { display: grid; grid-template-columns: repeat(var(--days, 7), minmax(0, 1fr)); gap: 4px; }
.ui-daystrip__day { position: relative; display: grid; justify-items: center; gap: 2px; min-height: 58px; padding: 6px 0 8px; border-radius: var(--r-md); color: var(--muted); font-size: var(--fs-label-s); font-weight: var(--fw-semibold); }
.ui-daystrip__day b { display: grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; font-family: var(--font-display); font-size: var(--fs-title-l); font-weight: var(--fw-regular); color: var(--ink); }
.ui-daystrip__day:hover { background: var(--surface-3); }
.ui-daystrip__day[aria-current="date"] { color: var(--primary-ink); }
.ui-daystrip__day[aria-current="date"] b { color: var(--primary-ink); box-shadow: inset 0 0 0 1.5px var(--primary-ink); }
.ui-daystrip__day[aria-pressed="true"] b { background: var(--primary); color: var(--on-primary); box-shadow: none; }
.ui-daystrip__day.has-ev::after { content: ""; position: absolute; bottom: 3px; left: 50%; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--muted); }

/* Month grid. TODAY = primary text + ring · SELECTED = filled circle (same as mini-calendar).
   <div class="ui-month" aria-label="Septembrie 2026">
     <div class="ui-month__dow" aria-hidden="true">L</div>…
     <button class="ui-month__cell is-today" aria-current="date" aria-pressed="false" data-date="2026-09-25">
       <span class="ui-month__num" aria-hidden="true">25</span><span class="ui-sr-only">vineri, 25 septembrie, </span>
       <span class="ui-month__ev ui-sub--sport">Educație fizică</span><span class="ui-month__dots ui-sub--sport" aria-hidden="true"><i></i></span></button>
   Event labels show when the GRID is ≥ 770px wide (≈110px/column, container query); dots below. */
.ui-month { container-type: inline-size; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; background: var(--line); gap: 1px; }
.ui-month__dow { background: var(--surface-2); padding: 8px 4px; text-align: center; font-size: var(--fs-label-s); font-weight: var(--fw-semibold); color: var(--muted); text-transform: uppercase; letter-spacing: .06em; }
.ui-month__cell { position: relative; display: flex; flex-direction: column; gap: 3px; min-height: 56px; min-width: 0; padding: 6px; background: var(--surface); text-align: left; transition: background-color var(--dur-1); }
button.ui-month__cell:hover { background: var(--surface-2); }
.ui-month__num { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; font-size: var(--fs-label); font-weight: var(--fw-semibold); font-variant-numeric: tabular-nums; }
.ui-month__cell.is-muted { background: var(--surface-muted); }
.ui-month__cell.is-muted .ui-month__num { color: var(--muted); font-weight: var(--fw-regular); }
.ui-month__cell.is-today .ui-month__num { color: var(--primary-ink); font-weight: var(--fw-bold); box-shadow: inset 0 0 0 1.5px var(--primary-ink); }
.ui-month__cell.is-selected .ui-month__num, .ui-month__cell[aria-pressed="true"] .ui-month__num { background: var(--primary); color: var(--on-primary); box-shadow: none; }
.ui-month__cell.is-holiday { background: var(--accent-soft); }
.ui-month__ev { display: none; padding: 2px 6px; border-radius: 5px; background: var(--_bg, var(--primary-soft)); color: var(--_fg, var(--on-primary-soft)); font-size: var(--fs-label-s); font-weight: var(--fw-semibold); line-height: 1.25; overflow: hidden; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.ui-month__dots { display: flex; gap: 3px; padding-left: 9px; }
.ui-month__dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--_fg, var(--primary)); }
@container (min-width: 770px) {
  .ui-month__cell { min-height: 104px; padding: 8px; }
  .ui-month__ev { display: -webkit-box; }
  .ui-month__dots { display: none; }
}

/* Mini calendar (date picker / sidebar): same today/selected language as the month grid. */
.ui-minical { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; text-align: center; justify-items: center; }
.ui-minical__dow { font-size: var(--fs-label-s); font-weight: var(--fw-semibold); color: var(--muted); padding: 4px 0; }
.ui-minical__day { position: relative; display: grid; place-items: center; width: min(100%, 36px); aspect-ratio: 1; border-radius: 50%; font-size: var(--fs-label); font-variant-numeric: tabular-nums; }
@media (pointer: coarse) { .ui-minical__day { width: min(100%, 44px); } } /* 44px when the column allows it */
.ui-minical__day:hover { background: var(--surface-3); }
.ui-minical__day.is-muted { color: var(--muted); }
.ui-minical__day.is-today, .ui-minical__day[aria-current="date"] { color: var(--primary-ink); font-weight: var(--fw-bold); box-shadow: inset 0 0 0 1.5px var(--primary-ink); }
.ui-minical__day.is-selected, .ui-minical__day[aria-pressed="true"] { background: var(--primary); color: var(--on-primary); font-weight: var(--fw-semibold); box-shadow: none; }
.ui-minical__day.has-ev::after { content: ""; position: absolute; bottom: 4px; width: 4px; height: 4px; border-radius: 50%; background: var(--muted); }
.ui-minical__day.is-selected.has-ev::after, .ui-minical__day[aria-pressed="true"].has-ev::after { background: var(--on-primary); }

/* Agenda (mobile list of a day): day header + rows */
.ui-dayhead { display: flex; align-items: baseline; gap: var(--sp-2); padding: var(--sp-4) 0 var(--sp-2); }
.ui-dayhead--sticky { position: sticky; top: calc(var(--appbar-h) + var(--safe-top)); background: var(--paper); z-index: var(--z-raised); }
.ui-dayhead b { font-family: var(--font-display); font-size: var(--fs-display-s); font-weight: var(--fw-regular); }
.ui-dayhead span { font-size: var(--fs-body-s); color: var(--muted); }
.ui-dayhead.is-today b { color: var(--primary-ink); }

/* ---------- 17. Data table (desktop) -------------------------------- */
/* <div class="ui-table-wrap"><table class="ui-table ui-table--fixed"><colgroup><col style="width:44%">…</colgroup>…
   Row states: .is-open (the row shown in the side panel: tint + 3px bar),
   .is-review (needs a human: bold title + accent dot), .is-selected (checkbox). */
.ui-table-wrap { overflow: auto; max-width: 100%; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); box-shadow: var(--sh-1); }
.ui-table-wrap--tall { max-height: 480px; }
.ui-table { width: 100%; font-size: var(--fs-body-s); border-collapse: separate; border-spacing: 0; }
.ui-table--fixed { table-layout: fixed; }
.ui-table--fixed td, .ui-table--fixed th { overflow: hidden; text-overflow: ellipsis; }
.ui-table th { position: sticky; top: 0; z-index: 1; background: var(--surface-2); text-align: left; font-size: var(--fs-caption); font-weight: var(--fw-semibold); color: var(--muted); letter-spacing: .03em; padding: 11px 16px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.ui-table td { padding: 12px 16px; border-bottom: 1px solid var(--line); vertical-align: middle; white-space: nowrap; }
.ui-table td.is-wrap { white-space: normal; min-width: 220px; }
.ui-table--fixed td.is-wrap { min-width: 0; }
.ui-table tbody tr:last-child td { border-bottom: 0; }
.ui-table tbody tr { transition: background-color var(--dur-1); }
.ui-table tbody tr:hover { background: var(--surface-2); }
.ui-table tr.is-selected { background: var(--surface-3); }
.ui-table tr.is-open { background: var(--primary-soft); }
.ui-table tr.is-open > :first-child { box-shadow: inset 3px 0 0 var(--primary-ink); }
.ui-table tr.is-review .ui-table__primary { font-weight: var(--fw-bold); }
.ui-table tr.is-review .ui-table__primary::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 8px; border-radius: 50%; background: var(--accent); vertical-align: 1px; }
.ui-table .ui-num, .ui-table .is-num { text-align: right; font-variant-numeric: tabular-nums; }
.ui-table__primary { font-weight: var(--fw-semibold); display: block; overflow: hidden; text-overflow: ellipsis; }
.ui-table__primary a, .ui-table__primary button { color: inherit; font: inherit; text-align: left; }
.ui-table__sub { display: block; font-size: var(--fs-caption); color: var(--muted); font-weight: var(--fw-regular); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-table__sub .ui-i { display: inline-block; width: 14px; height: 14px; margin-right: 5px; vertical-align: -2px; }
.ui-table__check { width: 44px; padding-right: 0 !important; }
.ui-table .ui-check { min-height: 0; padding: 0; }

/* ---------- 18. App shell (mobile + desktop) ----------------------- */
/* Brand tile "0B" — deep green in both themes. */
.ui-brand { display: inline-flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.ui-brand__tile { display: grid; place-items: center; width: 40px; height: 40px; flex-shrink: 0; border-radius: 12px; background: var(--brand-tile-bg); color: var(--brand-tile-fg); font-weight: var(--fw-bold); font-size: var(--fs-title); letter-spacing: -.04em; }
.ui-brand__tile--sm { width: 34px; height: 34px; border-radius: 10px; font-size: var(--fs-button); }
.ui-brand__name { font-family: var(--font-display); font-size: var(--fs-title-l); line-height: 1.1; letter-spacing: var(--ls-display); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ui-brand__sub { display: block; font-family: var(--font-ui); font-size: var(--fs-label-s); font-weight: var(--fw-bold); letter-spacing: .12em; color: var(--muted); text-transform: uppercase; margin-top: 3px; }

/* Mobile top app bar (sticky, blurred).
   Large-title pattern (iOS large title / Flutter SliverAppBar.large):
   <header class="ui-appbar ui-appbar--large">{brand tile}<span class="ui-appbar__title">Azi</span>{actions}</header>
   then <div class="ui-pagehead"><h1 class="ui-pagehead__title">…</h1></div>;
   App.ui.bindLargeTitle(appbar, pageheadTitle) adds .is-scrolled when the
   large title passes under the bar — the small title fades in. */
.ui-appbar {
  position: sticky; top: 0; z-index: var(--z-header); display: flex; align-items: center; gap: var(--sp-2);
  min-height: calc(var(--appbar-h) + var(--safe-top)); padding: var(--safe-top) calc(var(--sp-2) + var(--safe-right)) 0 calc(var(--gutter) + var(--safe-left));
  background: var(--surface-glass); -webkit-backdrop-filter: saturate(1.6) blur(18px); backdrop-filter: saturate(1.6) blur(18px);
  border-bottom: 1px solid var(--line); transition: border-color var(--dur-2), background-color var(--dur-2);
}
.ui-appbar__title { flex: 1; min-width: 0; font-weight: var(--fw-semibold); font-size: var(--fs-title); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-appbar__actions { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.ui-appbar--large:not(.is-scrolled) { border-bottom-color: transparent; background: var(--paper); }
.ui-appbar--large .ui-appbar__title { opacity: 0; transform: translateY(6px); transition: opacity var(--dur-2) var(--ease-standard), transform var(--dur-2) var(--ease-standard); }
.ui-appbar--large.is-scrolled .ui-appbar__title { opacity: 1; transform: none; }
/* Large page title under the app bar */
.ui-pagehead { padding: var(--sp-5) 0 var(--sp-4); display: grid; gap: var(--sp-2); }
.ui-pagehead__title { font-family: var(--font-display); font-weight: var(--fw-regular); font-size: var(--fs-display-l); line-height: var(--lh-display-l); letter-spacing: var(--ls-display); text-wrap: balance; }
.ui-pagehead__date { font-size: var(--fs-title); font-weight: var(--fw-semibold); color: var(--ink-2); } /* key data at title size, not eyebrow */
.ui-pagehead__text { color: var(--muted); max-width: 62ch; font-size: var(--fs-body); }

/* Bottom tab bar (mobile). 4 navigation tabs + a raised circular Add in the
   centre (Flutter: BottomAppBar + FloatingActionButtonLocation.centerDocked).
   <nav class="ui-tabbar" aria-label="Navigare principală">
     <a class="ui-tabbar__item" aria-current="page"><span class="ui-tabbar__pill">{icon}</span>Azi</a> …
     <button class="ui-tabbar__add" type="button"><span class="ui-tabbar__add-btn">{icon plus}</span>Adaugă</button> …
     <a class="ui-tabbar__item"><span class="ui-tabbar__pill">{icon}</span><span class="ui-dot"></span>Mesaje<span class="ui-sr-only">, 3 noi</span></a></nav> */
.ui-tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-tabbar);
  display: grid; grid-template-columns: repeat(5, 1fr); align-items: start;
  min-height: calc(var(--tabbar-h) + var(--safe-bottom)); padding: 6px calc(4px + var(--safe-right)) var(--safe-bottom) calc(4px + var(--safe-left));
  background: var(--surface-glass); -webkit-backdrop-filter: saturate(1.6) blur(18px); backdrop-filter: saturate(1.6) blur(18px);
  border-top: 1px solid var(--line);
}
.ui-tabbar__item, .ui-tabbar__add { position: relative; display: grid; justify-items: center; align-content: start; gap: 3px; padding-top: 2px; min-height: 52px; color: var(--muted); font-size: clamp(11px, var(--fs-label-s), 14px); /* text scaling clamped ×1.3 like Flutter */ line-height: var(--lh-label-s); font-weight: var(--fw-semibold); letter-spacing: .01em; }
.ui-tabbar__item .ui-i { width: 23px; height: 23px; }
.ui-tabbar__pill { display: grid; place-items: center; width: 56px; height: 32px; border-radius: var(--r-pill); transition: background-color var(--dur-2) var(--ease-standard); }
.ui-tabbar__item[aria-current="page"] { color: var(--primary-ink); }
.ui-tabbar__item[aria-current="page"] .ui-tabbar__pill { background: var(--primary-soft); }
.ui-tabbar__item[aria-current="page"] .ui-i { stroke-width: 2; }
.ui-tabbar__item .ui-dot { position: absolute; top: 2px; left: calc(50% + 10px); }
.ui-tabbar__add { justify-self: stretch; }
/* 48px circle raised 8px above the bar edge; occupies 32px in flow so labels share a baseline. */
.ui-tabbar__add-btn { display: grid; place-items: center; width: 48px; height: 48px; margin-top: -16px; border-radius: 50%; background: var(--primary); color: var(--on-primary); box-shadow: var(--sh-fab), 0 0 0 4px var(--paper); transition: transform var(--dur-2) var(--ease-spring), background-color var(--dur-1); }
.ui-tabbar__add-btn .ui-i { width: 24px; height: 24px; stroke-width: 2.2; }
.ui-tabbar__add:hover .ui-tabbar__add-btn { background: var(--primary-hover); }
.ui-tabbar__add:active .ui-tabbar__add-btn { transform: scale(.92); }
@media (min-width: 1100px) { .ui-tabbar { display: none; } }
.ui-has-tabbar { padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom) + var(--sp-6)); }
@media (min-width: 1100px) { .ui-has-tabbar { padding-bottom: 0; } }

/* Desktop shell: sidebar | main | optional right panel
   <div class="ui-shell"><aside class="ui-sidenav">…</aside><main class="ui-main">…</main><aside class="ui-panel">…<div class="ui-panel__foot">…</div></aside></div> */
.ui-shell { display: grid; grid-template-columns: 1fr; min-height: 100dvh; }
@media (min-width: 1100px) {
  .ui-shell { grid-template-columns: var(--sidebar-w) minmax(0, 1fr); }
  .ui-shell--panel { grid-template-columns: var(--sidebar-w) minmax(0, 1fr) var(--panel-w); }
}
.ui-sidenav { display: none; }
@media (min-width: 1100px) {
  .ui-sidenav { display: flex; flex-direction: column; gap: var(--sp-1); position: sticky; top: 0; height: 100dvh; overflow-y: auto; padding: var(--sp-5) var(--sp-4); border-right: 1px solid var(--line); background: var(--paper); }
}
.ui-sidenav__brand { padding: 4px 8px var(--sp-5); }
.ui-sidenav__label { padding: var(--sp-5) 12px var(--sp-2); }
.ui-nav-item {
  display: flex; align-items: center; gap: 12px; min-height: 40px; padding: 0 12px; border-radius: 11px;
  color: var(--ink-2); font-size: var(--fs-button); font-weight: var(--fw-medium); transition: background-color var(--dur-1), color var(--dur-1);
}
.ui-nav-item .ui-i { width: 19px; height: 19px; color: var(--muted); }
.ui-nav-item:hover { background: var(--surface-3); color: var(--ink); }
.ui-nav-item[aria-current="page"] { background: var(--primary-soft); color: var(--on-primary-soft); font-weight: var(--fw-semibold); }
.ui-nav-item[aria-current="page"] .ui-i { color: var(--primary-ink); }
.ui-nav-item .ui-count { margin-left: auto; }
.ui-sidenav__foot { margin-top: auto; padding-top: var(--sp-4); border-top: 1px solid var(--line); }
.ui-main { min-width: 0; padding: var(--sp-6) var(--gutter) var(--sp-9); }
@media (min-width: 1100px) { .ui-main { padding: var(--sp-8) var(--sp-9) var(--sp-10); } }
/* Right panel scrolls; its __foot sticks to the bottom so decisive actions never leave the screen. */
.ui-panel { --_pad: var(--sp-6); display: none; }
@media (min-width: 1100px) { .ui-panel { display: block; position: sticky; top: 0; height: 100dvh; overflow-y: auto; padding: var(--_pad); border-left: 1px solid var(--line); background: var(--surface-2); } }
.ui-panel__foot {
  position: sticky; bottom: calc(var(--_pad) * -1); z-index: var(--z-raised); display: flex; gap: var(--sp-2);
  margin: var(--sp-5) calc(var(--_pad) * -1) calc(var(--_pad) * -1); padding: var(--sp-4) var(--_pad);
  background: var(--surface-2); border-top: 1px solid var(--line);
}
/* Desktop top bar inside main (title + search + actions) */
.ui-topbar { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.ui-topbar .ui-search { flex: 1; min-width: 200px; max-width: 420px; }
.ui-topbar__actions { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }

/* ---------- 19. Forced colours (Windows High Contrast) ------------- */
@media (forced-colors: active) {
  .ui-switch input { border: 2px solid CanvasText; }
  .ui-switch input::before { background: CanvasText; forced-color-adjust: none; }
  .ui-switch input:checked { background: Highlight; border-color: Highlight; forced-color-adjust: none; }
  .ui-switch input:checked::before { background: HighlightText; }
  .ui-radio input:checked::after { background: CanvasText; forced-color-adjust: none; }
  .ui-seg__btn[aria-checked="true"], .ui-seg__btn[aria-selected="true"], .ui-seg__btn[aria-pressed="true"],
  .ui-chip[aria-pressed="true"], .ui-chip[aria-selected="true"], .ui-chip.is-active,
  .ui-daystrip__day[aria-pressed="true"], .ui-month__cell[aria-pressed="true"], .ui-minical__day[aria-pressed="true"] { outline: 2px solid Highlight; outline-offset: -2px; forced-color-adjust: none; }
  .ui-dot, .ui-month__dots i, .ui-row.is-unread .ui-row__title::after, .ui-tab::after { background: CanvasText; forced-color-adjust: none; }
  .ui-aud, .ui-state, .ui-badge, .ui-count, .ui-sub-tag { border: 1px solid CanvasText; }
  .ui-aud-option:has(input:checked) { outline: 3px solid Highlight; }
  .ui-progress__bar { background: Highlight; forced-color-adjust: none; }
}

/* ---------- 20. Motion preferences --------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; scroll-behavior: auto !important; }
  /* A frozen 35% bar would look like real progress: show a static striped full bar instead. */
  .ui-progress--indeterminate .ui-progress__bar { left: 0; width: 100%; animation: none !important; background-image: repeating-linear-gradient(135deg, transparent 0 6px, color-mix(in srgb, var(--surface) 45%, transparent) 6px 12px); }
}
