/* Shy-玻璃 — component styles. Every value comes from tokens.css; nothing here re-declares a token. */

@property --sg-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@property --sg-mx { syntax: "<percentage>"; inherits: true; initial-value: 50%; }
@property --sg-my { syntax: "<percentage>"; inherits: true; initial-value: 50%; }

body { margin: 0; font-family: var(--font-sans); background: var(--mist-000); color: var(--ink); -webkit-font-smoothing: antialiased; }
.sg-stage { padding: var(--space-6); display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
.sg-stage--col { flex-direction: column; align-items: stretch; }
.sg-stage--mist { min-height: 100vh; box-sizing: border-box; align-content: flex-start; background:
  radial-gradient(40% 60% at 15% 20%, color-mix(in srgb, var(--glow-indigo) 30%, transparent), transparent 70%),
  radial-gradient(35% 50% at 85% 80%, color-mix(in srgb, var(--glow-teal) 30%, transparent), transparent 70%),
  var(--mist-000); }

/* ---------- focus: double ring, always ≥3:1 on mist, glass or nebula ---------- */
.sg-focusable:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
/* anything focusable the system did not style still gets a visible ring, scrollable regions included (zero specificity, so components win) */
:where(:focus-visible) { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
/* a container that took focus (it scrolls, or has a tabindex) usually fills the frame that clips it: its ring is drawn inside, where overflow: hidden cannot cut it off */
:where(:focus-visible):not(:where(button, a, input, select, textarea, summary, label)) { outline-offset: -2px; }

/* ---------- browser surfaces: selection, caret, scrollbars and numerals belong to the system too ---------- */
::selection { background: var(--selection); }
:where(html) { caret-color: var(--ink); accent-color: var(--ink); scrollbar-color: var(--scrollbar) transparent; }
:where(*) { scrollbar-width: thin; }
:where(time, td, th, output, kbd, .sg-num) { font-variant-numeric: tabular-nums; }

/* ---------- grain: the texture that makes nebula and pulse surfaces feel physical ---------- */
.sg-grain::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0; border-radius: inherit;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: var(--grain); mix-blend-mode: overlay;
}

/* ---------- shared motion primitives ---------- */
.sg-press { transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-press:active { transform: scale(.96); }
@keyframes sg-spin { to { --sg-angle: 360deg; } }
@keyframes sg-blur-in { from { opacity: 0; filter: blur(6px); transform: translateY(4px) scale(.98); } to { opacity: 1; filter: blur(0); transform: none; } }
@keyframes sg-reveal-x { from { clip-path: inset(-20% 100% -20% 0); } to { clip-path: inset(-20% 0 -20% 0); } }
@keyframes sg-drift { 0% { rotate: 0deg; scale: 1; } 50% { rotate: 8deg; scale: 1.08; } 100% { rotate: -6deg; scale: 1.02; } }
@keyframes sg-dot-pulse { 0%, 100% { opacity: .22; scale: .7; } 40% { opacity: 1; scale: 1; } }
.sg-blur-in { animation: sg-blur-in var(--duration-smooth) var(--ease-liquid) both; }

/* ---------- Icon ---------- */
.sg-icon { width: 20px; height: 20px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }

/* ---------- Button ---------- */
.sg-btn { position: relative; isolation: isolate; font: inherit; font-size: 15px; font-weight: 500; line-height: 1; height: var(--control-md); padding: 0 22px; border-radius: var(--radius-pill);
  display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; border: 1px solid transparent; white-space: nowrap;
  transition: transform var(--duration-quick) var(--ease-liquid), background-color var(--duration-instant), box-shadow var(--duration-base) var(--ease-liquid); }
/* not while keyboard-focused: the hover shadow would replace the focus ring when the pointer rests on the button */
.sg-btn:not([disabled]):hover:not(:focus-visible) { box-shadow: var(--shadow-lift); }
.sg-btn:active { transform: scale(.96); }
.sg-btn--ink { background: var(--ink); color: var(--ink-inverse); box-shadow: var(--shadow-lift); }
.sg-btn--glass { background: var(--glass-strong); color: var(--ink); border-color: var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-btn--ghost { background: transparent; color: var(--ink); border-color: var(--line-strong); }
/* danger: the one irreversible primary action of a view (delete, remove); lifts only on hover */
.sg-btn--danger { background: var(--status-bad); color: var(--on-status-bad); }
.sg-btn--sm { height: var(--control-sm); padding: 0 14px; font-size: 13px; }
.sg-btn--block { display: flex; width: 100%; justify-content: center; }
.sg-btn[disabled] { opacity: var(--disabled); cursor: not-allowed; transform: none; }
/* metal: a live liquid-metal ring around an ink core */
.sg-btn--metal { background: var(--ink); color: var(--ink-inverse); border: 0; padding: 0 24px; box-shadow: 0 10px 24px -10px rgba(20,25,35,.6); }
.sg-btn--metal::before { content: ""; position: absolute; inset: -2px; border-radius: inherit; z-index: -1; padding: 2px;
  background: conic-gradient(from var(--sg-angle), #6b7280, #f8fafc, #9ca3af, #e5e7eb, #4b5563, #f1f5f9, #6b7280);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
  animation: sg-spin var(--duration-loop) linear infinite; }
.sg-btn--metal::after { content: ""; position: absolute; inset: 0; border-radius: inherit; z-index: -1; pointer-events: none;
  background: radial-gradient(120% 140% at var(--sg-mx) -20%, rgba(255,255,255,.28), transparent 55%); transition: --sg-mx var(--duration-smooth) var(--ease-liquid); }
.sg-btn--metal.is-chromatic::before { background: conic-gradient(from var(--sg-angle), var(--glow-teal), #ffffff, var(--glow-magenta), var(--glow-indigo), #ffffff, var(--glow-ember), var(--glow-teal)); }
.sg-btn--metal:not([disabled]):hover::before { animation-duration: calc(var(--duration-loop) / 3); }

/* ---------- IconButton ---------- */
.sg-iconbtn { width: var(--control-md); height: var(--control-md); border-radius: var(--radius-pill); display: inline-grid; place-items: center; cursor: pointer; padding: 0;
  background: var(--glass); color: var(--ink); border: 1px solid var(--line-strong);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm));
  transition: transform var(--duration-quick) var(--ease-liquid), background-color var(--duration-instant); }
/* hover, like press, only while enabled: a disabled button stays as drawn */
.sg-iconbtn:not([disabled]):hover { background: var(--glass-strong); }
.sg-iconbtn:not([disabled]):hover .sg-icon { transform: translate(1px, -1px); }
.sg-iconbtn .sg-icon { transition: transform var(--duration-base) var(--ease-spring-bouncy); }
.sg-iconbtn:active { transform: scale(.92); }
.sg-iconbtn--sm { width: var(--control-sm); height: var(--control-sm); }
.sg-iconbtn--sm .sg-icon { width: 16px; height: 16px; }
.sg-iconbtn--xs { width: var(--control-xs); height: var(--control-xs); }
.sg-iconbtn--xs .sg-icon { width: 14px; height: 14px; }
.sg-iconbtn--lg { width: 56px; height: 56px; }
.sg-iconbtn--nebula { background: rgba(255,255,255,.06); color: var(--on-nebula); border-color: rgba(255,255,255,.5); }
.sg-iconbtn--nebula:not([disabled]):hover { background: rgba(255,255,255,.14); }
/* ghost: no fill, no border; for table rows, toolbars and buttons inside inputs. The hover nudge of the arrow icon is not wanted here. */
.sg-iconbtn--ghost { background: transparent; border-color: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
.sg-iconbtn--ghost:not([disabled]):hover { background: var(--state-hover); }
.sg-iconbtn--ghost:not([disabled]):active { background: var(--state-pressed); }
.sg-iconbtn--ghost:not([disabled]):hover .sg-icon { transform: none; }
.sg-iconbtn--ghost.sg-iconbtn--nebula { background: transparent; border-color: transparent; }
.sg-iconbtn--ghost.sg-iconbtn--nebula:not([disabled]):hover { background: rgba(255,255,255,.14); }
.sg-iconbtn[disabled] { opacity: var(--disabled); cursor: not-allowed; transform: none; }

/* ---------- PillTabs (gliding indicator) ---------- */
.sg-tabs { position: relative; display: flex; gap: var(--space-2); overflow-x: auto; scrollbar-width: none; padding: 4px; margin: -2px; } /* 4px of room keeps the double focus ring from being clipped by the scroller; the −2px margin keeps the layout where it was */
.sg-tabs::-webkit-scrollbar { display: none; }
.sg-tab { position: relative; z-index: 1; font: inherit; font-size: 15px; font-weight: 500; height: 44px; padding: 0 20px; max-width: 168px; flex: none; border-radius: var(--radius-pill);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer;
  background: var(--glass); color: var(--ink-2); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm));
  transition: background-color var(--duration-base) var(--ease-liquid), color var(--duration-base), border-color var(--duration-base), transform var(--duration-quick) var(--ease-liquid); }
.sg-tab:hover { color: var(--ink); }
.sg-tab:active { transform: scale(.96); }
.sg-tab[aria-selected="true"] { background: transparent; color: var(--ink); border-color: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
[data-theme="dark"] .sg-tab[aria-selected="true"] { color: var(--ink-inverse); }
.sg-tab[aria-selected="true"]:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-tabs-ind { position: absolute; z-index: 0; top: 4px; left: 0; height: 44px; border-radius: var(--radius-pill); background: var(--solid); box-shadow: var(--shadow-lift);
  transition: transform var(--duration-spring) var(--ease-spring-soft), width var(--duration-spring) var(--ease-spring-soft); pointer-events: none; }
.sg-tabs--sm .sg-tab { height: 32px; padding: 0 14px; font-size: 13px; }
.sg-tabs--sm .sg-tabs-ind { height: 32px; }

/* ---------- GlassCard (+ pointer spotlight) ---------- */
.sg-glass { position: relative; border-radius: var(--radius-md); padding: var(--space-6); color: var(--ink);
  background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4);
  transition: transform var(--duration-base) var(--ease-liquid), box-shadow var(--duration-base) var(--ease-liquid); }
.sg-glass--lg { border-radius: var(--radius-lg); padding: var(--space-8); }
.sg-glass--strong { background: var(--glass-strong); }
.sg-glass--spot::before { content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; opacity: 0;
  background: radial-gradient(240px circle at var(--sg-mx) var(--sg-my), color-mix(in srgb, var(--glass-edge) 70%, transparent), transparent 70%);
  transition: opacity var(--duration-smooth) var(--ease-liquid); }
.sg-glass--spot:hover::before { opacity: 1; }
/* lifting says “you can press this”: only cards with an action lift */
.sg-glass.is-interactive { cursor: pointer; transition: transform var(--duration-base) var(--ease-liquid), box-shadow var(--duration-base) var(--ease-liquid); }
.sg-glass.is-interactive:hover { transform: translateY(-2px); box-shadow: var(--shadow-glass), var(--shadow-lift); }
.sg-glass.is-interactive:active { transform: translateY(0) scale(.99); }
.sg-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); position: relative; }
.sg-card-title { margin: 0; font-size: 17px; line-height: 24px; font-weight: 500; }
.sg-card-sub { margin: 2px 0 0; font-size: 12px; line-height: 16px; color: var(--ink-2); }

/* ---------- NebulaPanel (drifting light + pointer parallax) ---------- */
.sg-nebula { position: relative; isolation: isolate; overflow: hidden; border-radius: var(--radius-xl); padding: var(--space-8);
  color: var(--on-nebula); background: var(--nebula-deep);
  box-shadow: var(--shadow-float), inset 0 0 0 1px rgba(255,255,255,.10), inset 0 0 48px rgba(255,255,255,.10); }
.sg-nebula::before { content: ""; position: absolute; inset: -18%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(34% 22% at 46% 96%, var(--nebula-glow) 0%, transparent 100%),
    radial-gradient(50% 42% at 34% 82%, var(--nebula-teal) 0%, transparent 100%),
    radial-gradient(38% 48% at 92% 56%, var(--nebula-mauve) 0%, transparent 100%),
    radial-gradient(56% 44% at 46% 40%, var(--nebula-indigo) 0%, transparent 100%);
  translate: calc((var(--sg-mx) - 50%) * .12) calc((var(--sg-my) - 50%) * .12);
  transition: --sg-mx var(--duration-slow) var(--ease-liquid), --sg-my var(--duration-slow) var(--ease-liquid);
  animation: sg-drift var(--duration-drift) var(--ease-in-out) infinite alternate; }
.sg-nebula > .sg-nebula-body { position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--space-6); height: 100%; }
.sg-nebula-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-4); }
.sg-nebula-title { margin: 0; font-size: 24px; line-height: 30px; font-weight: 400; letter-spacing: -.01em; }
.sg-nebula-foot { display: flex; align-items: center; justify-content: center; gap: var(--space-3); font-size: 17px; text-shadow: 0 1px 8px rgba(8,14,30,.45); }
.sg-nebula--compact { border-radius: var(--radius-lg); padding: var(--space-6); }

/* ---------- DotNumber (+ rolling digits) ---------- */
.sg-dot { white-space: nowrap; font-family: var(--font-dot); font-weight: 800; font-variation-settings: "ROND" 100; letter-spacing: .02em; font-variant-numeric: tabular-nums; line-height: 1; }
/* the point is one grid dot (Doto dot 0.082em) centred in a grid cell: 2.2 pitches from the nearest column of either neighbour, on the bottom row */
.sg-dot-point { display: inline-block; width: .1em; height: .1em; margin: 0 .12em 0 0; vertical-align: 0;
  background: radial-gradient(circle at 50% 50%, currentColor calc(.041em - .3px), transparent calc(.041em + .3px)); }
.sg-dot--glow .sg-dot-point { filter: drop-shadow(0 0 10px rgba(255,255,255,.55)) drop-shadow(0 0 2px rgba(255,255,255,.8)); }
.sg-dot-comma { width: .1em; height: .16em; border-radius: .05em .05em .08em .08em; margin: 0 .06em; vertical-align: -.06em; background: currentColor; }
.sg-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sg-dot--glow { text-shadow: 0 0 10px rgba(255,255,255,.55), 0 0 2px rgba(255,255,255,.8); }
/* a rolling digit sits in an overflow:hidden window that would cut its text-shadow into a box: glow outside the window instead */
.sg-dot--glow .sg-roll { text-shadow: none; filter: drop-shadow(0 0 10px rgba(255,255,255,.55)) drop-shadow(0 0 2px rgba(255,255,255,.8)); }
.sg-dot-unit { font-family: var(--font-sans); font-size: 13px; font-weight: 500; margin-left: var(--space-1); letter-spacing: 0; text-shadow: none; }
/* vertical-align puts the window's bottom edge so that a rolling digit stands exactly where a static one does (measured: -.12em left rolling digits .03em too high) */
.sg-roll { display: inline-block; height: 1em; overflow: hidden; vertical-align: -.15em; padding: 0 .02em; margin: 0 -.02em; }
.sg-roll-strip { display: flex; flex-direction: column; transition: transform var(--duration-spring) var(--ease-spring-bouncy), filter var(--duration-smooth) var(--ease-liquid); }
.sg-roll-strip > span { height: 1em; line-height: 1; }
.sg-roll.is-moving .sg-roll-strip { filter: blur(.6px); }

/* ---------- DeltaChip ---------- */
.sg-chip { display: inline-flex; align-items: center; gap: 3px; height: 26px; padding: 0 10px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap; font-variant-numeric: tabular-nums;
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-chip .sg-icon { width: 13px; height: 13px; stroke-width: 2; }
.sg-chip--on-color { color: var(--on-pulse); background: rgba(255,255,255,.14); border: 1px solid rgba(255,255,255,.7); box-shadow: inset 0 1px 0 rgba(255,255,255,.5); }
.sg-chip--surface { color: var(--ink); background: var(--glass-strong); border: 1px solid var(--line); }
.sg-chip--surface.is-up .sg-icon { color: var(--status-good); }
.sg-chip--surface.is-down .sg-icon { color: var(--status-bad); }
.sg-chip > * { animation: sg-blur-in var(--duration-smooth) var(--ease-liquid) both; }
.sg-chip-base { font-weight: 400; margin-left: 2px; }

/* ---------- MetricPill (liquid capsule; the glow follows the pointer) ---------- */
.sg-pill { --tone: var(--pulse-indigo); --tone-glow: var(--glow-indigo); --sg-mx: 92%; --sg-my: 110%;
  position: relative; isolation: isolate; overflow: hidden; border-radius: var(--radius-pill); min-height: 112px; box-sizing: border-box;
  padding: 20px 28px 22px; color: var(--on-pulse); display: flex; flex-direction: column; justify-content: center; gap: 10px;
  background:
    radial-gradient(60% 70% at var(--sg-mx) var(--sg-my), color-mix(in srgb, var(--tone-glow) 55%, transparent), transparent 70%),
    radial-gradient(50% 60% at 6% -10%, color-mix(in srgb, var(--tone-glow) 45%, transparent), transparent 70%),
    var(--tone);
  box-shadow: inset 0 0 22px 2px color-mix(in srgb, var(--tone-glow) 55%, transparent), inset 0 1px 0 rgba(255,255,255,.55),
    0 22px 40px -22px var(--tone);
  transition: transform var(--duration-smooth) var(--ease-spring-soft), --sg-mx var(--duration-slow) var(--ease-liquid), --sg-my var(--duration-slow) var(--ease-liquid); }
.sg-pill::before { content: ""; position: absolute; inset: 7px; border-radius: inherit; border: 1px dashed rgba(255,255,255,.42); pointer-events: none; z-index: 0;
  transition: inset var(--duration-smooth) var(--ease-spring-soft); }
.sg-pill > * { position: relative; z-index: 1; }
.sg-pill.is-interactive { cursor: pointer; }
.sg-pill.is-interactive:hover { transform: translateY(-3px) scale(1.015); }
.sg-pill.is-interactive:active { transform: scale(.98); }
.sg-pill:hover::before { inset: 5px; }
.sg-pill:active { transform: scale(.98); }
.sg-pill--magenta { --tone: var(--pulse-magenta); --tone-glow: var(--glow-magenta); }
.sg-pill--indigo { --tone: var(--pulse-indigo); --tone-glow: var(--glow-indigo); }
.sg-pill--ember { --tone: var(--pulse-ember); --tone-glow: var(--glow-ember); }
.sg-pill--teal { --tone: var(--pulse-teal); --tone-glow: var(--glow-teal); }
.sg-pill-label { text-align: center; font-size: 13px; line-height: 18px; font-weight: 500; }
.sg-pill-base { font-weight: 400; }
.sg-pill-base::before { content: " · "; }
/* in a capsule the baseline rides on the label line; the chip keeps it for screen readers only */
.sg-pill .sg-chip-base { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.sg-pill-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.sg-pill-row .sg-chip { align-self: center; }
.sg-pill--sm { min-height: 88px; padding: 14px 22px 16px; gap: 6px; }
.sg-add { min-height: 112px; border-radius: var(--radius-pill); border: 0; background: var(--solid); color: var(--ink); box-shadow: var(--shadow-lift);
  display: grid; place-items: center; cursor: pointer; font: inherit; transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-add:active { transform: scale(.96); }
.sg-add .sg-icon { width: 26px; height: 26px; stroke-width: 1.25; transition: transform var(--duration-spring) var(--ease-spring-bouncy); }
.sg-add:hover .sg-icon { transform: rotate(90deg); }
[data-theme="dark"] .sg-add { color: var(--ink-inverse); }
.sg-add--sm { min-height: 88px; }

/* ---------- StatFigure ---------- */
.sg-stat { display: flex; flex-direction: column; gap: var(--space-1); color: var(--ink); }
/* 40px 以上的静态大数字用比例数字：等宽的“1”两侧会散开；表格、输入、计数器保持等宽 */
.sg-stat-value { display: flex; align-items: flex-start; gap: 2px; font-variant-numeric: proportional-nums; }
.sg-stat-value > span[class^="numeral"] { animation: sg-blur-in var(--duration-smooth) var(--ease-liquid) both; }
.sg-stat-affix { font-size: 15px; line-height: 20px; font-weight: 400; color: var(--ink-2); margin-top: 6px; }
.sg-stat-label { font-size: 12px; line-height: 16px; color: var(--ink-2); display: flex; align-items: center; gap: var(--space-2); }

/* ---------- SignalCurve ---------- */
.sg-curve { display: block; width: 100%; height: auto; overflow: visible; touch-action: none; }
.sg-curve-draw { animation: sg-reveal-x var(--duration-slow) var(--ease-liquid) both; }
.sg-curve-line { fill: none; stroke-width: 2; stroke-linecap: round; }
.sg-curve-dots { fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-dasharray: .1 5; }
.sg-curve-grid { stroke-width: 1; stroke-linecap: round; stroke-dasharray: .1 5; fill: none; }
.sg-curve-lens { transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-curve-clip { transition: x var(--duration-spring) var(--ease-spring-soft), width var(--duration-spring) var(--ease-spring-soft); }
.sg-curve-drop { transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-curve--nebula { color: var(--on-nebula); }
.sg-curve--nebula .sg-curve-line, .sg-curve--nebula .sg-curve-dots { stroke: var(--on-nebula); }
.sg-curve--nebula .sg-curve-grid { stroke: rgba(243,245,249,.55); }
.sg-curve--nebula .sg-curve-lens-glass { fill: rgba(255,255,255,.16); stroke: rgba(255,255,255,.6); }
.sg-curve--nebula .sg-curve-tip { fill: var(--on-nebula); }
.sg-curve--surface { color: var(--ink); }
.sg-curve--surface .sg-curve-line, .sg-curve--surface .sg-curve-dots { stroke: var(--ink); }
.sg-curve--surface .sg-curve-grid { stroke: var(--ink-3); }
.sg-curve--surface .sg-curve-lens-glass { fill: var(--glass-strong); stroke: var(--line-strong); }
.sg-curve--surface .sg-curve-tip { fill: var(--ink); }
.sg-curve-label { font-family: var(--font-sans); font-size: 12px; font-weight: 500; fill: currentColor; }

/* ---------- DayDial (gliding day) ---------- */
.sg-dial { display: flex; flex-direction: column; gap: var(--space-5); align-items: stretch; }
.sg-dial-days { position: relative; display: flex; justify-content: space-between; gap: var(--space-1); }
.sg-day { position: relative; z-index: 1; width: 40px; height: auto; aspect-ratio: 1; flex: 0 1 40px; min-width: 28px; border-radius: var(--radius-pill); font: inherit; font-size: 12px; font-weight: 500; cursor: pointer; padding: 0;
  background: transparent; transition: color var(--duration-base) var(--ease-liquid), border-color var(--duration-base), transform var(--duration-quick) var(--ease-liquid); }
.sg-day:active { transform: scale(.9); }
.sg-dial--nebula .sg-day { color: var(--on-nebula); border: 1px solid rgba(255,255,255,.45); }
.sg-dial--surface .sg-day { color: var(--ink-2); border: 1px solid var(--line-strong); }
.sg-day[aria-pressed="true"] { border-color: transparent; color: var(--nebula-deep); }
.sg-dial--surface .sg-day[aria-pressed="true"] { color: var(--ink); }
[data-theme="dark"] .sg-dial--surface .sg-day[aria-pressed="true"] { color: var(--ink-inverse); }
.sg-dial-ind { position: absolute; z-index: 0; top: 0; left: 0; width: var(--sg-day-w, 40px); height: var(--sg-day-w, 40px); border-radius: var(--radius-pill); background: var(--solid); box-shadow: var(--shadow-lift);
  transition: transform var(--duration-spring) var(--ease-spring-soft); pointer-events: none; }
.sg-dial-range { display: flex; align-items: center; justify-content: center; gap: var(--space-3); font-size: 17px; line-height: 24px; }
.sg-dial-range > span { display: inline-block; }
.sg-dial-range button { background: none; border: 0; padding: 4px; color: inherit; cursor: pointer; display: inline-grid; place-items: center; border-radius: var(--radius-pill);
  transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-dial-range button:active { transform: scale(.85); }
.sg-dial-range .sg-icon { width: 16px; height: 16px; }
.sg-dial--nebula .sg-dial-range { text-shadow: 0 1px 8px rgba(8,14,30,.5); }

/* ---------- BorderBeam: a soft light riding the edge ---------- */
.sg-beam { position: relative; isolation: isolate; border-radius: var(--radius-md); }
.sg-beam::before, .sg-beam::after { content: ""; position: absolute; inset: calc(var(--sg-beam-w, 1.5px) * -1); border-radius: inherit; pointer-events: none; z-index: 2;
  padding: var(--sg-beam-w, 1.5px);
  background: conic-gradient(from var(--sg-angle), transparent 0 64%, color-mix(in srgb, var(--sg-beam-c, var(--glow-teal)) 70%, transparent) 76%, #ffffff 82%, var(--sg-beam-c2, var(--glow-indigo)) 88%, transparent 96%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude;
  animation: sg-spin var(--sg-beam-d, var(--duration-loop)) linear infinite; }
.sg-beam::after { filter: blur(8px); opacity: .8; padding: calc(var(--sg-beam-w, 1.5px) * 3); inset: calc(var(--sg-beam-w, 1.5px) * -3); }
.sg-beam > * { border-radius: inherit; }
.sg-beam--pulse { --sg-beam-c: var(--glow-magenta); --sg-beam-c2: var(--glow-ember); }
.sg-beam--mono { --sg-beam-c: var(--ink-3); --sg-beam-c2: var(--ink); }
.sg-beam.is-paused::before, .sg-beam.is-paused::after { animation-play-state: paused; opacity: 0; transition: opacity var(--duration-smooth); }

/* ---------- ThinkingOrb / MatrixLoader ---------- */
.sg-orb { display: inline-block; vertical-align: middle; }
.sg-matrix { display: inline-grid; grid-template-columns: repeat(4, var(--sg-mx-dot, 6px)); gap: var(--sg-mx-gap, 4px); color: inherit; }
.sg-matrix > i { width: var(--sg-mx-dot, 6px); height: var(--sg-mx-dot, 6px); border-radius: 50%; background: currentColor;
  animation: sg-dot-pulse calc(var(--duration-loop) / 4) var(--ease-in-out) infinite both; }

/* ---------- GooeyMenu: a liquid + that splits into actions ---------- */
.sg-goo { position: relative; width: var(--sg-goo-size, 56px); height: var(--sg-goo-size, 56px); }
.sg-goo-blobs { position: absolute; inset: -120px; pointer-events: none; }
.sg-goo-blob, .sg-goo-btn { position: absolute; left: 50%; top: 50%; width: var(--sg-goo-size, 56px); height: var(--sg-goo-size, 56px); margin: calc(var(--sg-goo-size, 56px) / -2);
  border-radius: 50%; transition: transform var(--duration-spring) var(--ease-spring-bouncy); transition-delay: var(--sg-d, 0ms); }
.sg-goo-blob { background: var(--sg-goo-c, var(--ink)); }
.sg-goo-blob.is-main { transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-goo-btn { display: grid; place-items: center; border: 0; padding: 0; cursor: pointer; background: transparent; color: var(--sg-goo-on, var(--ink-inverse)); font: inherit; }
.sg-goo-btn.is-action { width: 44px; height: 44px; margin: -22px; opacity: 0; transition: transform var(--duration-spring) var(--ease-spring-bouncy), opacity var(--duration-base) var(--ease-liquid); transition-delay: var(--sg-d, 0ms); }
.sg-goo.is-open .sg-goo-btn.is-action { opacity: 1; }
.sg-goo-btn .sg-icon { transition: transform var(--duration-spring) var(--ease-spring-bouncy); }
/* the box must not scale: a separate `scale` is applied after `transform`, so it would also scale the translate and drag the icon behind its drop. The same grow-in lives on the icon instead (same duration, curve and stagger delay). */
.sg-goo-btn.is-action .sg-icon { scale: .4; transition: transform var(--duration-spring) var(--ease-spring-bouncy) 0ms, scale var(--duration-spring) var(--ease-spring-bouncy) var(--sg-d, 0ms); }
.sg-goo.is-open .sg-goo-btn.is-action .sg-icon { scale: 1; }
.sg-goo-btn.is-action:not(:focus-visible):hover .sg-icon { scale: 1.1; }
.sg-goo.is-open .sg-goo-btn.is-toggle .sg-icon { transform: rotate(135deg); }
.sg-goo-blob.is-action { width: 44px; height: 44px; margin: -22px; }
.sg-goo-tip { position: absolute; left: 50%; bottom: calc(100% + 6px); translate: -50% 0; font-size: 12px; white-space: nowrap; color: var(--ink); background: var(--glass-strong);
  border: 1px solid var(--line); border-radius: var(--radius-xs); padding: 4px 8px; opacity: 0; pointer-events: none; transition: opacity var(--duration-quick); }
.sg-goo-btn:hover .sg-goo-tip, .sg-goo-btn:focus-visible .sg-goo-tip { opacity: 1; }

/* ---------- Tilt: pointer-driven 3D tilt with a glass glare ---------- */
.sg-tilt { perspective: 900px; display: block; }
.sg-tilt-inner { position: relative; transform-style: preserve-3d; border-radius: inherit;
  transform: rotateX(var(--sg-rx, 0deg)) rotateY(var(--sg-ry, 0deg)); transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-tilt.is-active .sg-tilt-inner { transition: transform var(--duration-quick) linear; }
.sg-tilt-glare { position: absolute; inset: 0; z-index: 3; border-radius: var(--sg-tilt-r, var(--radius-xl)); pointer-events: none; mix-blend-mode: soft-light; opacity: 0;
  background: radial-gradient(60% 60% at var(--sg-mx) var(--sg-my), rgba(255,255,255,.75), transparent 60%);
  transition: opacity var(--duration-smooth) var(--ease-liquid); }
.sg-tilt.is-active .sg-tilt-glare { opacity: 1; }

/* ---------- Switch: spring thumb that stretches like liquid ---------- */
.sg-switch { position: relative; display: inline-flex; align-items: center; gap: var(--space-3); cursor: pointer; font-size: 15px; color: var(--ink); background: none; border: 0; padding: 0; font-family: inherit; }
.sg-switch-track { position: relative; width: 52px; height: 32px; border-radius: var(--radius-pill); background: var(--mist-200); border: 1px solid var(--line-strong); box-sizing: border-box;
  transition: background-color var(--duration-base) var(--ease-liquid), border-color var(--duration-base); }
.sg-switch-thumb { position: absolute; top: 3px; left: 3px; width: 24px; height: 24px; border-radius: var(--radius-pill); background: var(--solid); box-shadow: var(--shadow-lift);
  transition: transform var(--duration-spring) var(--ease-spring-bouncy), width var(--duration-base) var(--ease-liquid), background-color var(--duration-base); }
.sg-switch:not([disabled]):active .sg-switch-thumb { width: 30px; }
.sg-switch[aria-checked="true"] .sg-switch-track { background: var(--ink); border-color: var(--ink); }
.sg-switch[aria-checked="true"] .sg-switch-thumb { transform: translateX(20px); background: var(--ink-inverse); }
.sg-switch[aria-checked="true"]:not([disabled]):active .sg-switch-thumb { transform: translateX(14px); }
.sg-switch[disabled] { opacity: var(--disabled); cursor: not-allowed; }
/* the ring follows the pill track, not the whole button with its label */
.sg-switch.sg-focusable:focus-visible { box-shadow: none; }
.sg-switch:focus-visible .sg-switch-track { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }

/* ---------- GlassIsland: a pill that morphs between compact and expanded ---------- */
.sg-island { position: relative; overflow: hidden; color: var(--on-nebula); background: var(--nebula-deep); border-radius: 28px; cursor: pointer; border: 0; padding: 0; font: inherit; text-align: left;
  box-shadow: var(--shadow-float), inset 0 0 0 1px rgba(255,255,255,.12);
  transition: width var(--duration-smooth) var(--ease-spring-soft), height var(--duration-smooth) var(--ease-spring-soft), border-radius var(--duration-smooth) var(--ease-spring-soft); }
.sg-island.is-open { border-radius: 36px; }
.sg-island-face { position: absolute; top: 0; left: 0; padding: 10px 16px; box-sizing: border-box; white-space: nowrap;
  transition: opacity var(--duration-base) var(--ease-liquid), filter var(--duration-base) var(--ease-liquid), transform var(--duration-smooth) var(--ease-spring-soft); }
.sg-island-face.is-hidden { opacity: 0; filter: blur(8px); transform: scale(.94); pointer-events: none; }
.sg-island-face.is-expanded { padding: 20px 24px; }

/* ---------- BottomSheet: draggable glass sheet with snap points ---------- */
.sg-sheet-scrim { position: absolute; inset: 0; z-index: 20; background: var(--scrim); opacity: 0; pointer-events: none;
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); transition: opacity var(--duration-smooth) var(--ease-liquid); }
.sg-sheet-scrim.is-on { opacity: 1; pointer-events: auto; }
.sg-sheet { position: absolute; left: 8px; right: 8px; bottom: 0; box-sizing: border-box; z-index: 21; border-radius: var(--radius-lg) var(--radius-lg) 0 0; padding: 8px var(--space-5) var(--space-6);
  background: var(--glass-overlay); border: 1px solid var(--line); box-shadow: var(--shadow-float); color: var(--ink);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4);
  touch-action: none; transition: transform var(--duration-smooth) var(--ease-spring-soft); }
.sg-sheet.is-dragging { transition: none; }
.sg-sheet-handle { width: 40px; height: 5px; border-radius: var(--radius-pill); background: var(--ink-3); margin: 0 auto var(--space-4); cursor: grab; }
.sg-sheet-handle { position: relative; }
.sg-sheet-handle::after { content: ""; position: absolute; inset: -12px -12px; } /* a 64×29 grab area around the 40×5 bar */

/* ================= Infinite canvas ================= */
.sg-canvas { container-type: inline-size; position: relative; overflow: hidden; isolation: isolate; outline: none; user-select: none; -webkit-user-select: none; touch-action: none;
  background-color: var(--mist-000); border-radius: var(--radius-lg); min-height: 320px; cursor: default; }
.sg-canvas:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-canvas--dots { background-image: radial-gradient(circle, var(--canvas-dot) 1.1px, transparent 1.7px); }
.sg-canvas--lines { background-image: linear-gradient(var(--canvas-grid) 1px, transparent 1px), linear-gradient(90deg, var(--canvas-grid) 1px, transparent 1px); }
.sg-canvas--none { background-image: none; }
.sg-canvas--glow::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(40% 50% at 20% 25%, color-mix(in srgb, var(--glow-indigo) 22%, transparent), transparent 70%),
    radial-gradient(36% 46% at 85% 80%, color-mix(in srgb, var(--glow-teal) 22%, transparent), transparent 70%); }
.sg-canvas.is-animating { transition: background-position var(--duration-smooth) var(--ease-spring-soft), background-size var(--duration-smooth) var(--ease-spring-soft); }
.sg-canvas.is-animating .sg-canvas-world { transition: transform var(--duration-smooth) var(--ease-spring-soft); }
.sg-canvas.is-hand { cursor: grab; }
.sg-canvas.is-panning, .sg-canvas.is-panning * { cursor: grabbing !important; }
.sg-canvas.is-connecting { cursor: crosshair; }
.sg-canvas-world { position: absolute; left: 0; top: 0; width: 0; height: 0; transform-origin: 0 0; }
.sg-canvas-edges { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; }
.sg-canvas-edges .sg-edge-hit { pointer-events: stroke; }

/* Edge */
.sg-edge { --ec: var(--port-any); }
.sg-edge--text { --ec: var(--port-text); } .sg-edge--image { --ec: var(--port-image); } .sg-edge--number { --ec: var(--port-number); } .sg-edge--audio { --ec: var(--port-audio); }
.sg-edge--st-ok { --ec: var(--status-good); } .sg-edge--st-running { --ec: var(--status-busy); } .sg-edge--st-warn { --ec: var(--status-warn); } .sg-edge--st-error { --ec: var(--status-bad); } .sg-edge--st-idle, .sg-edge--st-off { --ec: var(--status-idle); }
.sg-edge path { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.sg-edge-hit { stroke: transparent; stroke-width: 16; cursor: pointer; }
.sg-edge-line { stroke: var(--edge-idle); stroke-width: 2; stroke-dasharray: .1 6; transition: stroke var(--duration-base) var(--ease-liquid); }
.sg-edge.is-done .sg-edge-line, .sg-edge.is-flow .sg-edge-line { stroke: var(--ec); stroke-dasharray: none; }
.sg-edge.is-flow .sg-edge-line { stroke-opacity: .45; }
.sg-edge-flow { stroke: var(--ec); stroke-width: 2.5; stroke-dasharray: 10 14; animation: sg-edge-flow calc(var(--duration-loop) / 6) linear infinite; }
.sg-edge-dot { fill: var(--ec); filter: drop-shadow(0 0 4px var(--ec)); }
.sg-edge.is-error .sg-edge-line { stroke: var(--status-bad); stroke-dasharray: 6 6; }
.sg-edge.is-draft .sg-edge-line { stroke: var(--ec); stroke-dasharray: 4 6; animation: sg-edge-flow calc(var(--duration-loop) / 8) linear infinite; }
.sg-edge-halo { stroke: var(--canvas-select); stroke-width: 7; stroke-opacity: .22; }
.sg-edge.is-selected .sg-edge-line { stroke: var(--canvas-select); stroke-dasharray: none; stroke-width: 2.5; }
.sg-edge-trace { stroke: var(--ec); stroke-width: 3; stroke-dasharray: 1; stroke-dashoffset: 1; animation: sg-edge-trace var(--duration-slow) var(--ease-liquid) forwards; }
@keyframes sg-edge-flow { to { stroke-dashoffset: -24; } }
@keyframes sg-edge-trace { 0% { stroke-dashoffset: 1; opacity: 1; } 70% { stroke-dashoffset: 0; opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 0; } }
.sg-edge-label { position: absolute; left: 0; top: 0; white-space: nowrap; font-size: 11px; line-height: 20px; padding: 0 8px; border-radius: var(--radius-pill); color: var(--ink-2);
  background: var(--glass-strong); border: 1px solid var(--line); -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); pointer-events: none; }

/* Port */
.sg-port { --pc: var(--port-any); position: absolute; top: 50%; width: 12px; height: 12px; margin-top: -6px; border-radius: 50%; box-sizing: border-box;
  background: var(--mist-100); border: 2px solid var(--pc); cursor: crosshair; z-index: 2;
  transition: scale var(--duration-base) var(--ease-spring-bouncy), background-color var(--duration-quick), box-shadow var(--duration-base), opacity var(--duration-base); }
.sg-port::after { content: ""; position: absolute; inset: -9px; border-radius: 50%; }
.sg-port--in { left: -7px; } .sg-port--out { right: -7px; }
.sg-port--text { --pc: var(--port-text); } .sg-port--image { --pc: var(--port-image); } .sg-port--number { --pc: var(--port-number); } .sg-port--audio { --pc: var(--port-audio); }
.sg-port.is-connected { background: var(--pc); }
.sg-port:hover { scale: 1.35; }
.sg-port.is-valid { scale: 1.35; background: var(--pc); box-shadow: 0 0 0 5px color-mix(in srgb, var(--pc) 22%, transparent); animation: sg-port-pulse 1s var(--ease-in-out) infinite alternate; }
.sg-port.is-invalid { opacity: .3; }
@keyframes sg-port-pulse { to { box-shadow: 0 0 0 9px color-mix(in srgb, var(--pc) 6%, transparent); } }

/* Node */
.sg-node.is-initial { animation: none; }
.sg-node { position: relative; box-sizing: border-box; border-radius: var(--radius-md); color: var(--ink); font-size: 13px;
  background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4);
  transition: box-shadow var(--duration-base) var(--ease-liquid), scale var(--duration-base) var(--ease-spring-bouncy), border-color var(--duration-base);
  animation: sg-node-in var(--duration-smooth) var(--ease-liquid) backwards; }
@keyframes sg-pop { from { opacity: 0; filter: blur(6px); scale: .96; } }
@keyframes sg-node-in { from { opacity: 0; filter: blur(6px); scale: .96; } }
.sg-node.is-positioned { position: absolute; left: 0; top: 0; }
.sg-node.sg-beam { position: absolute; }
.sg-node:not(.is-positioned).sg-beam { position: relative; }
.sg-node.is-selected { border-color: transparent; box-shadow: 0 0 0 2px var(--canvas-select), var(--shadow-float); }
.sg-node.is-dragging { scale: 1.02; box-shadow: 0 0 0 2px var(--canvas-select), var(--shadow-float); z-index: 5; }
.sg-node:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-node-head { display: flex; align-items: center; gap: 10px; height: 48px; padding: 0 12px 0 12px; box-sizing: border-box; border-bottom: 1px solid var(--line); cursor: grab; }
.sg-node-icon { --nc: var(--pulse-indigo); width: 28px; height: 28px; flex: none; border-radius: 50%; display: grid; place-items: center; color: var(--on-pulse); background: var(--nc);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 4px 10px -4px var(--nc); }
.sg-acc--magenta { --nc: var(--pulse-magenta); --ng: var(--glow-magenta); } .sg-acc--indigo { --nc: var(--pulse-indigo); --ng: var(--glow-indigo); }
.sg-acc--ember { --nc: var(--pulse-ember); --ng: var(--glow-ember); } .sg-acc--teal { --nc: var(--pulse-teal); --ng: var(--glow-teal); }
.sg-acc--magenta .sg-node-icon, .sg-acc--indigo .sg-node-icon, .sg-acc--ember .sg-node-icon, .sg-acc--teal .sg-node-icon { --nc: inherit; }
.sg-node-title { flex: 1; min-width: 0; font-size: 14px; line-height: 20px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-node-status { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 8px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 500; flex: none;
  background: var(--mist-200); color: var(--ink); animation: sg-blur-in var(--duration-smooth) var(--ease-liquid) both; }
.sg-node-status.is-running { color: var(--ink); }
.sg-node-status.is-done .sg-icon { color: var(--status-good); stroke-width: 2.4; }
.sg-node-status.is-error .sg-icon { color: var(--status-bad); stroke-width: 2.4; }
.sg-node-ports { display: grid; grid-template-columns: 1fr 1fr; padding: 6px 0; }
.sg-node-col { display: grid; grid-auto-rows: 28px; align-content: start; }
.sg-node-row { position: relative; display: flex; align-items: center; padding: 0 14px; min-width: 0; }
.sg-node-col--out .sg-node-row { justify-content: flex-end; }
.sg-node-plabel { font-size: 12px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sg-node-body { padding: 0 14px 14px; cursor: default; }
.sg-node-ports + .sg-node-body { padding-top: 2px; }
.sg-node-head + .sg-node-body { padding-top: 12px; }
/* nebula node: the one output that matters */
.sg-node--nebula { color: var(--on-nebula); border-color: rgba(255,255,255,.12);
  background: radial-gradient(60% 50% at 30% 100%, var(--nebula-teal), transparent 100%), radial-gradient(50% 60% at 100% 40%, var(--nebula-mauve), transparent 100%),
    radial-gradient(70% 60% at 40% 20%, var(--nebula-indigo), transparent 100%), var(--nebula-deep);
  box-shadow: var(--shadow-float), inset 0 0 0 1px rgba(255,255,255,.08); }
.sg-node--nebula .sg-node-head { border-bottom-color: rgba(255,255,255,.12); }
.sg-node--nebula .sg-node-plabel { color: var(--on-nebula-2); }
.sg-node--nebula .sg-port { background: var(--nebula-deep); --pc: var(--glow-indigo); }
.sg-node--nebula .sg-port--image { --pc: var(--glow-magenta); } .sg-node--nebula .sg-port--number { --pc: var(--glow-teal); } .sg-node--nebula .sg-port--audio { --pc: var(--glow-ember); } .sg-node--nebula .sg-port--any { --pc: var(--on-nebula-2); }
.sg-node--nebula .sg-port.is-connected { background: var(--pc); }
.sg-node--nebula .sg-node-status { background: rgba(255,255,255,.14); color: var(--on-nebula); }
.sg-node--nebula .sg-node-status.is-done .sg-icon { color: var(--glow-teal); }
/* note node: a liquid sticky */
.sg-node--note { color: var(--on-pulse); border: 0; background: radial-gradient(70% 80% at 100% 110%, color-mix(in srgb, var(--ng) 55%, transparent), transparent 70%), var(--nc);
  box-shadow: inset 0 0 18px 1px color-mix(in srgb, var(--ng) 50%, transparent), inset 0 1px 0 rgba(255,255,255,.5), 0 18px 34px -18px var(--nc); }
.sg-node--note .sg-node-head { border-bottom: 1px dashed rgba(255,255,255,.4); }
.sg-node--note .sg-node-icon { background: rgba(255,255,255,.18); box-shadow: inset 0 0 0 1px rgba(255,255,255,.6); }
.sg-node--note .sg-node-body { font-size: 13px; line-height: 19px; }

/* Group */
.sg-group { position: absolute; left: 0; top: 0; box-sizing: border-box; border-radius: var(--radius-lg);
  border: 1.5px dashed color-mix(in srgb, var(--nc) 55%, transparent); background: color-mix(in srgb, var(--nc) 6%, transparent); }
.sg-group-title { position: absolute; left: 14px; top: -30px; height: 24px; display: inline-flex; align-items: center; padding: 0 10px; border-radius: var(--radius-pill);
  font-size: 12px; font-weight: 500; color: var(--on-pulse); background: var(--nc); cursor: grab; white-space: nowrap; }

/* Cursor */
.sg-cursor { position: absolute; left: 0; top: 0; transform-origin: 0 0; pointer-events: none; z-index: 20; transition: transform 120ms linear; }
.sg-cursor svg { display: block; filter: drop-shadow(0 2px 3px rgba(0,0,0,.25)); }
.sg-cursor path { fill: var(--nc); stroke: #ffffff; stroke-width: 1.2; stroke-linejoin: round; }
.sg-cursor-name { position: absolute; left: 14px; top: 16px; white-space: nowrap; font-size: 12px; line-height: 20px; padding: 0 8px; border-radius: var(--radius-pill); color: var(--on-pulse); background: var(--nc); }

/* Overlays: marquee, node toolbar, picker, minimap, controls, tool dock */
.sg-marquee { position: absolute; z-index: 15; border: 1px solid var(--canvas-select); background: var(--canvas-select-fill); border-radius: 4px; pointer-events: none; }
.sg-canvas-ui { z-index: 16; }
.sg-canvas .sg-picker, .sg-canvas .sg-nodebar { z-index: 18; }
.sg-nodebar { position: absolute; transform: translate(-50%, -100%); display: inline-flex; align-items: center; gap: 2px; padding: 4px; border-radius: var(--radius-pill);
  background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-lift); -webkit-backdrop-filter: blur(var(--blur-lg)); backdrop-filter: blur(var(--blur-lg));
  animation: sg-pop var(--duration-base) var(--ease-liquid) backwards; white-space: nowrap; }
.sg-nodebar-btn { height: 30px; min-width: 30px; padding: 0 8px; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--ink); cursor: pointer; display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: 12px;
  transition: background-color var(--duration-instant), transform var(--duration-quick) var(--ease-liquid); }
.sg-nodebar-btn:hover { background: var(--mist-200); }
.sg-nodebar-btn:active { transform: scale(.92); }
.sg-nodebar-btn.is-danger .sg-icon { color: var(--status-bad); }
.sg-nodebar-sep, .sg-ctl-sep { width: 1px; height: 18px; background: var(--line); margin: 0 4px; flex: none; }
.sg-picker { position: absolute; width: 240px; padding: 8px; border-radius: var(--radius-md); background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-float);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4); animation: sg-pop var(--duration-base) var(--ease-liquid) backwards; color: var(--ink); }
.sg-picker-q { width: 100%; box-sizing: border-box; height: 36px; border-radius: var(--radius-sm); border: 1px solid var(--line-strong); background: var(--mist-100); color: var(--ink); padding: 0 12px; font: inherit; font-size: 13px; outline: none; }
.sg-picker-q:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-picker-list { display: grid; gap: 2px; margin-top: 6px; max-height: 240px; overflow: auto; }
.sg-picker-item { display: grid; grid-template-columns: 28px 1fr auto; gap: 10px; align-items: center; height: 40px; padding: 0 8px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--ink); cursor: pointer; font: inherit; font-size: 13px; text-align: left; }
.sg-picker-item:hover:not(:disabled) { background: var(--mist-200); }
.sg-picker-item:disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-picker-types { display: inline-flex; gap: 4px; }
.sg-picker-types .sg-port { position: static; margin: 0; width: 9px; height: 9px; cursor: inherit; }
.sg-picker-types .sg-port::after { content: none; }
.sg-picker-empty { padding: 12px; font-size: 12px; color: var(--ink-2); }
.sg-minimap { position: absolute; right: 12px; bottom: 12px; padding: 6px; border-radius: var(--radius-sm); background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-lift);
  -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md)); }
.sg-minimap svg { display: block; cursor: pointer; touch-action: none; }
.sg-minimap-node { fill: var(--nc); opacity: .75; }
.sg-minimap-node.is-nebula { fill: var(--nebula-deep); opacity: 1; }
.sg-minimap-view { fill: var(--canvas-select-fill); stroke: var(--canvas-select); stroke-width: 1.5; transition: x var(--duration-quick), y var(--duration-quick); }
.sg-canvas-controls, .sg-tooldock { position: absolute; display: flex; align-items: center; gap: 2px; padding: 4px; border-radius: var(--radius-pill);
  background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-lift); -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md)); }
.sg-canvas-controls { left: 12px; bottom: 12px; }
.sg-tooldock { left: 12px; top: 12px; flex-direction: column; }
.sg-tooldock .sg-ctl-sep { width: 18px; height: 1px; margin: 4px 0; }
.sg-ctl { height: 34px; min-width: 34px; padding: 0 8px; box-sizing: border-box; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--ink); cursor: pointer; display: inline-grid; place-items: center; font: inherit; font-size: 12px; font-variant-numeric: tabular-nums;
  transition: background-color var(--duration-instant), transform var(--duration-quick) var(--ease-liquid), box-shadow var(--duration-base); }
.sg-ctl:hover { background: var(--mist-200); }
.sg-ctl:active { transform: scale(.9); }
.sg-ctl--pct { min-width: 52px; }
.sg-ctl[aria-pressed="true"] { background: var(--solid); box-shadow: var(--shadow-lift); }
[data-theme="dark"] .sg-ctl[aria-pressed="true"] { color: var(--ink-inverse); }
.sg-ctl--add { background: var(--ink); color: var(--ink-inverse); }
.sg-ctl--add:hover { background: var(--ink); }
.sg-ctl--add .sg-icon { transition: transform var(--duration-spring) var(--ease-spring-bouncy); }
.sg-ctl--add:hover .sg-icon { transform: rotate(90deg); }

@media (prefers-reduced-motion: reduce) {
  .sg-edge-flow, .sg-edge.is-draft .sg-edge-line, .sg-port.is-valid, .sg-node, .sg-node-status, .sg-nodebar, .sg-picker { animation: none !important; }
  .sg-edge-trace { display: none; }
  .sg-edge-dot { display: none; }
  .sg-canvas.is-animating .sg-canvas-world, .sg-canvas.is-animating { transition: none; }
  .sg-cursor { transition: none; }
  .sg-light.is-running, .sg-light.is-error, .sg-light.is-pulse::after, .sg-ent--cell.is-running, .sg-ent.is-changed::after, .sg-bulkbar, .sg-ent.is-running .sg-ent-progress i { animation: none !important; }
}

/* ================= Node modules ================= */
/* StatusLight — shape carries the state as well as colour */
.sg-light { --sc: var(--status-idle); --lz: 8px; position: relative; display: inline-block; flex: none; width: var(--lz); height: var(--lz); box-sizing: border-box; vertical-align: middle;
  transition: background-color var(--duration-base) var(--ease-liquid), border-color var(--duration-base), scale var(--duration-base) var(--ease-spring-bouncy), rotate var(--duration-base) var(--ease-spring-bouncy), border-radius var(--duration-base); }
.sg-light--xs { --lz: 6px; } .sg-light--sm { --lz: 8px; } .sg-light--md { --lz: 10px; } .sg-light--lg { --lz: 14px; } .sg-light--xl { --lz: 20px; }
.sg-light.is-ok { --sc: var(--status-good); background: var(--sc); border-radius: 50%; box-shadow: 0 0 calc(var(--lz) * .9) color-mix(in srgb, var(--sc) 50%, transparent); }
.sg-light.is-running { --sc: var(--status-busy); border-radius: 50%; background: conic-gradient(var(--sc) 0 60%, color-mix(in srgb, var(--sc) 24%, transparent) 60% 100%); animation: sg-light-spin 1.1s linear infinite; }
.sg-light.is-warn { --sc: var(--status-warn); background: var(--sc); border-radius: 1.5px; scale: .8; rotate: 45deg; }
.sg-light.is-error { --sc: var(--status-bad); background: var(--sc); border-radius: 2px; animation: sg-light-blink 1.6s var(--ease-in-out) infinite; }
.sg-light.is-idle { --sc: var(--status-idle); background: var(--sc); border-radius: 50%; scale: .55; }
.sg-light.is-off { --sc: var(--status-idle); background: transparent; border: max(1.5px, calc(var(--lz) * .2)) solid var(--sc); border-radius: 50%; }
.sg-light.is-pulse::after { content: ""; position: absolute; inset: 0; border-radius: inherit; background: var(--sc); animation: sg-light-ping 2.4s var(--ease-liquid) infinite; }
@keyframes sg-light-spin { to { rotate: 360deg; } }
@keyframes sg-light-blink { 50% { opacity: .45; } }
@keyframes sg-light-ping { 0% { opacity: .55; scale: 1; } 70%, 100% { opacity: 0; scale: 2.6; } }

/* EntityNode */
.sg-ent { --sc: var(--status-idle); position: relative; box-sizing: border-box; color: var(--ink); font-size: 13px; cursor: pointer; outline: none; -webkit-user-select: none; user-select: none;
  transition: transform var(--duration-base) var(--ease-spring-bouncy), box-shadow var(--duration-base) var(--ease-liquid), background-color var(--duration-base), border-color var(--duration-base); }
.sg-ent.is-ok { --sc: var(--status-good); } .sg-ent.is-running { --sc: var(--status-busy); } .sg-ent.is-warn { --sc: var(--status-warn); } .sg-ent.is-error { --sc: var(--status-bad); }
.sg-ent:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); z-index: 3; }
.sg-ent.is-selected { box-shadow: 0 0 0 2px var(--canvas-select), 0 0 0 5px var(--canvas-select-fill); z-index: 2; }
.sg-ent.is-changed::after { content: ""; position: absolute; inset: -3px; border-radius: inherit; border: 2px solid var(--sc); pointer-events: none; animation: sg-ent-ripple 900ms var(--ease-liquid) forwards; }
@keyframes sg-ent-ripple { from { opacity: 1; scale: .92; } to { opacity: 0; scale: 1.3; } }
.sg-ent-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.sg-ent-sub { font-size: 12px; line-height: 16px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sg-ent-main { display: grid; min-width: 0; flex: 1; gap: 1px; }
.sg-ent-avatar { --nc: var(--pulse-indigo); position: relative; flex: none; width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; font-size: 13px; font-weight: 600; letter-spacing: .02em;
  color: var(--on-pulse); background: var(--nc); box-shadow: inset 0 1px 0 rgba(255,255,255,.4); }
.sg-acc--magenta .sg-ent-avatar, .sg-acc--indigo .sg-ent-avatar, .sg-acc--ember .sg-ent-avatar, .sg-acc--teal .sg-ent-avatar { --nc: inherit; }
.sg-ent-badge { position: absolute; right: -1px; bottom: -1px; box-shadow: 0 0 0 2.5px var(--mist-100); }
.sg-ent-badge.is-off { background: var(--mist-100); }
.sg-ent-badge.is-idle { scale: .8; }
/* light */
.sg-ent--light { display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; }
.sg-ent--light:hover { transform: scale(1.5); }
/* cell */
.sg-ent--cell { display: inline-grid; place-items: center; width: var(--sg-cell, 24px); height: var(--sg-cell, 24px); border-radius: 6px;
  background: color-mix(in srgb, var(--sc) 16%, var(--mist-100)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sc) 38%, transparent); }
.sg-ent--cell.is-idle, .sg-ent--cell.is-off { background: var(--mist-200); box-shadow: inset 0 0 0 1px var(--line); }
.sg-ent--cell:hover { transform: scale(1.3); z-index: 3; }
.sg-ent--cell.is-selected { box-shadow: 0 0 0 2px var(--canvas-select); }
.sg-ent--cell.is-running { background-image: linear-gradient(110deg, transparent 30%, color-mix(in srgb, var(--sc) 22%, transparent) 50%, transparent 70%); background-size: 250% 100%; animation: sg-ent-shimmer 1.6s linear infinite; }
@keyframes sg-ent-shimmer { from { background-position: 120% 0; } to { background-position: -120% 0; } }
/* chip */
.sg-ent--chip { display: inline-flex; align-items: center; gap: 8px; height: 34px; padding: 0 12px; border-radius: var(--radius-pill); background: var(--glass-strong); border: 1px solid var(--line); max-width: 100%; }
.sg-ent--chip .sg-ent-metric { margin-left: auto; padding-left: 6px; font-size: 12px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-ent--chip:hover { transform: translateY(-1px); box-shadow: var(--shadow-lift); }
.sg-ent--chip.is-selected { box-shadow: 0 0 0 2px var(--canvas-select); }
/* compact */
.sg-ent--compact { display: flex; align-items: center; gap: 12px; height: 64px; padding: 0 14px 0 12px; border-radius: 18px; background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-ent--compact .sg-ent-name { font-size: 14px; line-height: 20px; }
.sg-ent--compact .sg-ent-metric { display: grid; justify-items: end; flex: none; }
.sg-ent--compact .sg-ent-metric b { font-size: 15px; font-weight: 500; font-variant-numeric: tabular-nums; animation: sg-pop var(--duration-smooth) var(--ease-liquid) backwards; }
.sg-ent--compact .sg-ent-metric small { font-size: 11px; color: var(--ink-2); }
.sg-ent--compact:hover { transform: translateY(-2px); box-shadow: var(--shadow-glass), var(--shadow-lift); }
.sg-ent--compact.is-selected { box-shadow: 0 0 0 2px var(--canvas-select), var(--shadow-lift); }
.sg-ent--compact::before { content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px; border-radius: 0 3px 3px 0; background: var(--sc); opacity: 0; }
/* card + hero */
.sg-ent--card, .sg-ent--hero { display: grid; gap: 14px; padding: 16px; border-radius: var(--radius-md); align-content: start; }
.sg-ent--card { background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-glass); -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md)); }
.sg-ent--card:hover, .sg-ent--hero:hover { transform: translateY(-3px); }
.sg-ent--card:hover { box-shadow: var(--shadow-glass), var(--shadow-lift); }
.sg-ent--card.is-selected { box-shadow: 0 0 0 2px var(--canvas-select), var(--shadow-float); }
.sg-ent-head { display: flex; align-items: center; gap: 12px; }
.sg-ent--card .sg-ent-name, .sg-ent--hero .sg-ent-name { font-size: 15px; line-height: 20px; }
.sg-ent-state { display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 9px; flex: none; border-radius: var(--radius-pill); font-size: 12px; font-weight: 500;
  background: color-mix(in srgb, var(--sc) 13%, transparent); color: var(--ink); animation: sg-pop var(--duration-smooth) var(--ease-liquid) backwards; }
.sg-ent-big { display: flex; align-items: baseline; gap: 8px; }
.sg-ent-bigval { font-size: 32px; line-height: 36px; font-weight: 300; letter-spacing: -.02em; font-variant-numeric: tabular-nums; animation: sg-pop var(--duration-smooth) var(--ease-liquid) backwards; }
.sg-ent-biglabel { font-size: 12px; color: var(--ink-2); }
.sg-ent-spark { display: block; width: 100%; height: 36px; overflow: visible; }
.sg-ent-spark-line { fill: none; stroke: var(--sc); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.sg-ent-spark-area { fill: color-mix(in srgb, var(--sc) 14%, transparent); }
.sg-ent-progress { height: 6px; border-radius: var(--radius-pill); background: var(--mist-200); overflow: hidden; }
.sg-ent-progress i { display: block; height: 100%; border-radius: inherit; background: var(--sc); transition: width var(--duration-slow) var(--ease-spring-soft); }
.sg-ent.is-running .sg-ent-progress i { background-image: linear-gradient(90deg, transparent, rgba(255,255,255,.55), transparent); background-size: 50% 100%; background-repeat: no-repeat; animation: sg-ent-shimmer 1.4s linear infinite; background-color: var(--sc); }
.sg-ent-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.sg-ent-tags span { font-size: 12px; line-height: 20px; padding: 0 8px; border-radius: var(--radius-pill); background: var(--mist-200); color: var(--ink-2); }
.sg-ent-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.sg-ent--hero { color: var(--on-nebula); border: 1px solid rgba(255,255,255,.12); box-shadow: var(--shadow-float);
  background: radial-gradient(60% 50% at 30% 100%, var(--nebula-teal), transparent 100%), radial-gradient(50% 60% at 100% 40%, var(--nebula-mauve), transparent 100%), radial-gradient(70% 60% at 40% 20%, var(--nebula-indigo), transparent 100%), var(--nebula-deep); }
.sg-ent--hero.is-ok { --sc: var(--glow-teal); } .sg-ent--hero.is-running { --sc: var(--glow-indigo); } .sg-ent--hero.is-warn { --sc: var(--glow-ember); } .sg-ent--hero.is-error { --sc: var(--on-nebula-bad); } .sg-ent--hero.is-idle, .sg-ent--hero.is-off { --sc: var(--on-nebula-2); }
.sg-ent--hero .sg-light { --sc: inherit; }
.sg-ent--hero .sg-ent-sub, .sg-ent--hero .sg-ent-biglabel { color: var(--on-nebula-2); }
.sg-ent--hero .sg-ent-state { color: var(--on-nebula); background: rgba(255,255,255,.12); }
.sg-ent--hero .sg-ent-badge { box-shadow: 0 0 0 2.5px var(--nebula-deep); }
.sg-ent--hero .sg-ent-progress { background: rgba(255,255,255,.14); }
.sg-ent--hero .sg-ent-tags span { background: rgba(255,255,255,.12); color: var(--on-nebula); }
.sg-ent--hero.is-selected { box-shadow: 0 0 0 2px var(--canvas-select), var(--shadow-float); }
.sg-ent--hero .sg-ent-spark-area { fill: color-mix(in srgb, var(--sc) 22%, transparent); }

/* NodeGrid */
.sg-ngrid { position: relative; outline: none; touch-action: pan-y; padding: 8px; margin: -8px; border-radius: var(--radius-sm); }
.sg-ngrid-groups { display: grid; gap: 20px; }
.sg-ngrid-group { display: grid; gap: 10px; }
.sg-ngrid-ghead { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-2); }
.sg-ngrid-ghead b { font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.sg-ngrid-items { display: grid; gap: 10px; align-items: start; }
.sg-ngrid--light .sg-ngrid-items { grid-template-columns: repeat(auto-fill, 16px); gap: 8px; }
.sg-ngrid--cell .sg-ngrid-items { grid-template-columns: repeat(auto-fill, var(--sg-cell, 24px)); gap: 5px; }
.sg-ngrid--chip .sg-ngrid-items { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; }
.sg-ngrid--compact .sg-ngrid-items { grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); }
.sg-ngrid--card .sg-ngrid-items, .sg-ngrid--hero .sg-ngrid-items { grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); gap: 14px; }
.sg-ngrid-empty { background: var(--state-hover); border-radius: var(--radius-md); max-width: none; }
.sg-ntip { position: absolute; z-index: 20; transform: translate(-50%, calc(-100% - 10px)); pointer-events: none; min-width: 150px; max-width: 240px; padding: 10px 12px; border-radius: 12px; display: grid; gap: 4px;
  background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-lift); -webkit-backdrop-filter: blur(var(--blur-lg)); backdrop-filter: blur(var(--blur-lg));
  animation: sg-pop var(--duration-quick) var(--ease-liquid) backwards; color: var(--ink); }
.sg-ntip-name { font-size: 13px; font-weight: 500; }
.sg-ntip-row { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.sg-ntip-metric { margin-left: auto; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-ntip-sub { font-size: 12px; color: var(--ink-2); }

/* StatusSummary */
.sg-summary { display: grid; gap: 12px; }
.sg-summary-head { display: flex; align-items: baseline; gap: 12px; }
.sg-summary-total { display: inline-flex; align-items: baseline; gap: 4px; }
.sg-summary-total b { font-size: 40px; line-height: 44px; font-weight: 200; letter-spacing: -.02em; font-variant-numeric: proportional-nums; animation: sg-pop var(--duration-smooth) var(--ease-liquid) backwards; }
.sg-summary-total small { font-size: 13px; color: var(--ink-2); }
.sg-summary-title { font-size: 13px; color: var(--ink-2); }
.sg-summary-bar { display: flex; gap: 3px; height: 10px; }
.sg-summary-bar span { --sc: var(--status-idle); flex-basis: 0; min-width: 6px; border-radius: var(--radius-pill); background: var(--sc); transition: flex-grow var(--duration-slow) var(--ease-spring-soft), opacity var(--duration-base); }
.sg-summary-bar .is-ok { --sc: var(--status-good); } .sg-summary-bar .is-running { --sc: var(--status-busy); } .sg-summary-bar .is-warn { --sc: var(--status-warn); } .sg-summary-bar .is-error { --sc: var(--status-bad); }
.sg-summary-bar .is-off { background: transparent; box-shadow: inset 0 0 0 1.5px var(--sc); }
.sg-summary-bar .is-dim { opacity: .25; }
.sg-summary-legend { display: flex; flex-wrap: wrap; gap: 4px 6px; }
.sg-summary-item { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px 0 10px; border-radius: var(--radius-pill); border: 1px solid transparent; background: transparent; color: var(--ink-2); font: inherit; font-size: 13px; cursor: pointer;
  transition: background-color var(--duration-instant), border-color var(--duration-base), color var(--duration-base); }
.sg-summary-item:disabled { cursor: default; }
.sg-summary-item:not(:disabled):hover { background: var(--mist-200); color: var(--ink); }
.sg-summary-item b { font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; animation: sg-pop var(--duration-smooth) var(--ease-liquid) backwards; }
.sg-summary-item.is-on { background: var(--solid); border-color: transparent; color: var(--ink); box-shadow: var(--shadow-lift); }
[data-theme="dark"] .sg-summary-item.is-on { color: var(--ink-inverse); }
[data-theme="dark"] .sg-summary-item.is-on b { color: var(--ink-inverse); }

/* BulkBar */
.sg-bulkbar { display: inline-flex; align-items: center; gap: 2px; padding: 5px; border-radius: var(--radius-pill); color: var(--ink-inverse); background: var(--ink); box-shadow: var(--shadow-float);
  animation: sg-bulk-in var(--duration-spring) var(--ease-spring-bouncy) backwards; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
@keyframes sg-bulk-in { from { opacity: 0; translate: 0 16px; scale: .94; filter: blur(4px); } }
.sg-bulk-count { display: inline-flex; align-items: baseline; gap: 6px; padding: 0 10px 0 12px; font-size: 13px; white-space: nowrap; }
.sg-bulk-count b { font-size: 17px; font-weight: 500; font-variant-numeric: tabular-nums; animation: sg-pop var(--duration-base) var(--ease-liquid) backwards; }
.sg-bulkbar .sg-nodebar-sep { background: color-mix(in srgb, var(--ink-inverse) 25%, transparent); }
.sg-bulk-btn { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 12px; border: 0; border-radius: var(--radius-pill); background: transparent; color: inherit; font: inherit; font-size: 13px; cursor: pointer; white-space: nowrap;
  transition: background-color var(--duration-instant), transform var(--duration-quick) var(--ease-liquid); }
.sg-bulk-btn:hover { background: color-mix(in srgb, var(--ink-inverse) 14%, transparent); }
.sg-bulk-btn:active { transform: scale(.94); }
.sg-bulk-btn:disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-bulk-btn.is-danger .sg-icon { color: var(--on-nebula-bad); }
[data-theme="dark"] .sg-bulk-btn.is-danger .sg-icon { color: var(--status-bad); }
.sg-bulk-clear { padding: 0 10px; }
/* a phone is too narrow for a row of labelled actions: show icons only (the words stay for readers and as the tooltip) rather than hide the last ones behind an invisible sideways scroll */
@media (max-width: 479px) {
  .sg-bulk-btn { position: relative; padding: 0 10px; }
  .sg-bulk-lab { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}

/* entity nodes on the canvas */
.sg-node--entity { background: transparent; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; border-radius: 18px; }
.sg-node--entity.is-selected, .sg-node--entity.is-dragging { box-shadow: none; }
.sg-node--entity > .sg-ent { cursor: grab; }
.sg-node--entity .sg-ent--chip, .sg-node--entity .sg-ent--compact, .sg-node--entity .sg-ent--card, .sg-node--entity .sg-ent--hero { width: 100%; }
.sg-node--entity.is-tiny .sg-port { opacity: 0; pointer-events: none; }
.sg-node--entity .sg-port { top: 50%; }

@container (max-width: 560px) { .sg-minimap { display: none; } .sg-canvas-controls .sg-ctl--pct { min-width: 44px; } }

/* ---------- reduced motion: keep colour changes, drop movement ---------- */
@media (prefers-reduced-motion: reduce) {
  .sg-btn, .sg-iconbtn, .sg-tab, .sg-pill, .sg-day, .sg-curve-lens, .sg-tabs-ind, .sg-dial-ind, .sg-roll-strip, .sg-goo-blob, .sg-goo-btn, .sg-tilt-inner, .sg-switch-thumb, .sg-island, .sg-sheet, .sg-curve-clip, .sg-curve-drop, .sg-goo-btn .sg-icon, .sg-iconbtn .sg-icon, .sg-field-clear {
    transition-property: background-color, color, opacity !important; }
  .sg-nebula::before, .sg-beam::before, .sg-beam::after, .sg-btn--metal::before, .sg-matrix > i, .sg-curve-draw, .sg-blur-in, .sg-chip > *, .sg-stat-value > span { animation: none !important; }
  .sg-pill:hover, .sg-glass:hover, .sg-pill:active, .sg-glass:active { transform: none; }
  .sg-skel::after { display: none; }
  .sg-busy i { animation: none !important; opacity: .7; }
}

/* ---------- busy dots: the loading mark inside a control ---------- */
.sg-busy { display: inline-flex; align-items: center; gap: 3px; flex: none; }
.sg-busy i { width: 4px; height: 4px; border-radius: 50%; background: currentColor; animation: sg-dot-pulse 960ms var(--ease-in-out) infinite both; }
.sg-busy i:nth-child(2) { animation-delay: 120ms; }
.sg-busy i:nth-child(3) { animation-delay: 240ms; }
.sg-btn.is-loading { cursor: progress; }
.sg-btn.is-loading:active { transform: none; }

/* ---------- Skeleton ---------- */
.sg-skel { display: block; position: relative; overflow: hidden; background: var(--skeleton); border-radius: var(--radius-xs); }
.sg-skel::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--skeleton-shine), transparent); animation: sg-skel-sweep 1600ms var(--ease-in-out) infinite; }
@keyframes sg-skel-sweep { to { transform: translateX(100%); } }
.sg-skel--block { width: 100%; height: 120px; border-radius: var(--radius-sm); }
.sg-skel--text { width: 100%; height: 12px; border-radius: var(--radius-pill); }
.sg-skel--circle { width: 40px; height: 40px; border-radius: 50%; }
.sg-skel--pill { width: 160px; height: 44px; border-radius: var(--radius-pill); }
.sg-skel-stack { display: grid; gap: 10px; }
.sg-skel-stack .sg-skel--block { margin-bottom: 6px; }
.sg-nebula .sg-skel { background: color-mix(in srgb, var(--on-nebula) 10%, transparent); }

/* ---------- EmptyState ---------- */
.sg-empty { display: grid; justify-items: start; gap: var(--space-2); padding: var(--space-6); max-width: 46ch; }
.sg-empty-visual { margin-bottom: var(--space-2); color: var(--ink-2); }
.sg-empty-title { margin: 0; font-size: 17px; line-height: 24px; font-weight: 500; color: var(--ink); }
.sg-empty-desc { margin: 0; font-size: 15px; line-height: 22px; color: var(--ink-2); }
.sg-empty-action { margin-top: var(--space-2); display: flex; gap: var(--space-2); flex-wrap: wrap; }
.sg-empty--compact { padding: var(--space-4) var(--space-5); gap: var(--space-1); }
.sg-empty--compact .sg-empty-title { font-size: 15px; line-height: 22px; }
.sg-empty--compact .sg-empty-desc { font-size: 13px; line-height: 18px; }
/* inside a card the empty state shares the card's left edge */
.sg-glass .sg-empty, .sg-nebula .sg-empty { padding-left: 0; padding-right: 0; }
.sg-nebula .sg-empty-title { color: var(--on-nebula); } .sg-nebula .sg-empty-desc, .sg-nebula .sg-empty-visual { color: var(--on-nebula-2); }

/* ---------- TextField ---------- */
.sg-field { display: grid; gap: 6px; min-width: 0; align-content: start; }
.sg-field-label { display: flex; align-items: baseline; gap: var(--space-2); font-size: 13px; line-height: 18px; font-weight: 500; color: var(--ink); }
.sg-field-opt { font-size: 12px; font-weight: 400; color: var(--ink-2); }
.sg-field-box { position: relative; display: flex; align-items: center; gap: var(--space-2); height: var(--control-md); padding: 0 14px; box-sizing: border-box;
  border-radius: var(--radius-sm); background: var(--glass-strong); border: 1px solid var(--line-strong); color: var(--ink);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm));
  transition: border-color var(--duration-quick) var(--ease-liquid), box-shadow var(--duration-quick) var(--ease-liquid); }
.sg-field-box:hover { border-color: var(--ink-2); }
.sg-field-box:focus-within { border-color: var(--ink); box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-field-input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; outline: none; background: none; font: inherit; font-size: 15px; color: var(--ink); font-variant-numeric: tabular-nums; }
.sg-field-input::placeholder { color: var(--ink-2); opacity: 1; }
/* Urbanist's bullet is a 3px speck: masked text uses the system bullet, wide enough to count */
.sg-field-input[type="password"]:not(:placeholder-shown) { font-family: system-ui, sans-serif; letter-spacing: .08em; }
.sg-field-icon { width: 18px; height: 18px; color: var(--ink-2); }
.sg-field-prefix { font-size: 15px; color: var(--ink-2); white-space: nowrap; font-variant-numeric: tabular-nums; margin-right: -4px; }
.sg-field-suffix { font-size: 13px; color: var(--ink-2); white-space: nowrap; }
.sg-field-busy { color: var(--ink-2); }
.sg-field-hint { margin: 0; font-size: 12px; line-height: 16px; color: var(--ink-2); }
.sg-field-error { margin: 0; display: flex; align-items: flex-start; gap: 6px; font-size: 12px; line-height: 16px; color: var(--status-bad); }
.sg-field-error .sg-icon { flex: none; margin-top: 1px; }
.sg-field.is-error .sg-field-box { border-color: var(--status-bad); }
.sg-field.is-error .sg-field-box:focus-within { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--status-bad); }
.sg-field.is-disabled { opacity: var(--disabled); }
.sg-field.is-disabled .sg-field-box:hover { border-color: var(--line-strong); }
.sg-field.is-disabled .sg-field-input { cursor: not-allowed; }
.sg-field--sm .sg-field-box { height: var(--control-sm); padding: 0 12px; }
.sg-field--sm .sg-field-input, .sg-field--sm .sg-field-prefix { font-size: 14px; }
/* a trailing action (clear, show password) is a 24px ghost button: the right padding shrinks (minus the 1px border) so the button keeps the same margin to the box edge on top, bottom and right */
.sg-field-box.has-action { padding-right: calc((var(--control-md) - var(--control-xs)) / 2 - 1px); }
.sg-field--sm .sg-field-box.has-action { padding-right: calc((var(--control-sm) - var(--control-xs)) / 2 - 1px); }
.sg-field-clear { transition: transform var(--duration-quick) var(--ease-liquid), background-color var(--duration-instant), opacity var(--duration-quick) var(--ease-liquid), visibility 0s; }
.sg-field-clear.is-hidden { opacity: 0; visibility: hidden; transition: opacity var(--duration-quick) var(--ease-liquid), visibility 0s linear var(--duration-quick); }
/* hint or error on the left, character count on the right */
.sg-field-foot { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.sg-field-foot > .sg-field-hint, .sg-field-foot > .sg-field-error { flex: 1; min-width: 0; }
.sg-field-count { margin-left: auto; flex: none; font-size: 12px; line-height: 16px; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sg-field-count.is-over { color: var(--status-bad); }

/* ---------- touch: small controls keep their look but get a 44px hit area under a finger ---------- */
@media (pointer: coarse) {
  .sg-btn--sm:not(.sg-btn--metal), .sg-iconbtn--sm, .sg-iconbtn--xs, .sg-tab, .sg-switch, .sg-bulk-btn, .sg-nodebar-btn, .sg-ctl, .sg-summary-item, .sg-dial-range button, .sg-sheet-handle, .sg-goo-btn { position: relative; }
  .sg-switch::after, .sg-bulk-btn::after, .sg-nodebar-btn::after, .sg-ctl::after, .sg-summary-item::after { content: ""; position: absolute; inset: -6px; }
  /* these have a 1px border and an absolutely positioned ::after starts at the padding edge, so they reach 1px further to make a full 44px */
  .sg-btn--sm:not(.sg-btn--metal)::after, .sg-iconbtn--sm::after { content: ""; position: absolute; inset: -7px; }
  .sg-iconbtn--xs::after { content: ""; position: absolute; inset: -11px; }
  /* an input is not covered by a pseudo-element (taps would stop placing the caret): the 32px field grows 6px above and below instead; a press there focuses the input */
  .sg-field--sm .sg-field-box::before, .sg-field--sm .sg-field-box::after { content: ""; position: absolute; left: -1px; right: -1px; height: 6px; }
  .sg-field--sm .sg-field-box::before { top: -7px; }
  .sg-field--sm .sg-field-box::after { bottom: -7px; }
  /* the strip is painted after the box's children: lift the clear / show-password button above it so its 44px hit area stays whole */
  .sg-field--sm .sg-field-box > .sg-iconbtn { z-index: 1; }
  .sg-dial-range button::after { content: ""; position: absolute; inset: -10px; }
  .sg-sheet-handle::after { inset: -20px -16px; }
  .sg-tabs--sm .sg-tab, .sg-tabs--sm .sg-tabs-ind { height: 40px; }
}

/* ---------- shared primitives (P): floating glass, scrim, option rows, keycaps, input-shell variants ---------- */

/* recipe D — every panel that hangs off <body>: glass-overlay + blur-lg + 1px line + shadow-float.
   useFloating writes top / left and --sg-origin (toward the anchor), --sg-avail-h / --sg-avail-w (room on the chosen side), --sg-anchor-w. */
.sg-overlay { position: fixed; box-sizing: border-box; margin: 0; color: var(--ink); font-family: var(--font-sans); font-size: 15px; line-height: 22px;
  background: var(--glass-overlay); border: 1px solid var(--line); box-shadow: var(--shadow-float);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4);
  max-height: var(--sg-avail-h, 100vh); max-width: var(--sg-avail-w, 100vw); overflow: auto; overscroll-behavior: contain; outline: none;
  transform-origin: var(--sg-origin, 50% 0); }
.sg-overlay--menu { border-radius: var(--radius-sm); padding: 4px; min-width: 180px; max-width: min(320px, var(--sg-avail-w, 100vw)); }
.sg-overlay--panel { border-radius: var(--radius-md); padding: var(--space-4); }
/* enter: fade + scale .96 + 4px toward the anchor; exit: 2/3 of the time, fade and a slight shrink */
.sg-overlay[data-side="bottom"] { --sg-ov-dx: 0px; --sg-ov-dy: -4px; }
.sg-overlay[data-side="top"] { --sg-ov-dx: 0px; --sg-ov-dy: 4px; }
.sg-overlay[data-side="right"] { --sg-ov-dx: -4px; --sg-ov-dy: 0px; }
.sg-overlay[data-side="left"] { --sg-ov-dx: 4px; --sg-ov-dy: 0px; }
.sg-overlay[data-state="open"] { animation: sg-ov-in var(--duration-quick) var(--ease-liquid) both; }
.sg-overlay[data-state="closed"] { animation: sg-ov-out calc(var(--duration-quick) * 2 / 3) var(--ease-exit) both; pointer-events: none; }
.sg-overlay[data-instant][data-state="open"] { animation: none; }
@keyframes sg-ov-in { from { opacity: 0; transform: translate(var(--sg-ov-dx, 0px), var(--sg-ov-dy, -4px)) scale(.96); } }
@keyframes sg-ov-out { to { opacity: 0; transform: scale(.98); } }
@keyframes sg-ov-fade { from { opacity: 0; } }
@keyframes sg-ov-fade-out { to { opacity: 0; } }

/* scrim under modal panels (Dialog, Drawer, CommandPalette) */
.sg-scrim { position: fixed; inset: 0; z-index: var(--z-overlay); background: var(--scrim);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-scrim[data-state="open"] { animation: sg-ov-fade var(--duration-base) var(--ease-liquid) both; }
.sg-scrim[data-state="closed"] { animation: sg-ov-fade-out calc(var(--duration-base) * 2 / 3) var(--ease-exit) both; pointer-events: none; }
.sg-scrim[data-instant][data-state="open"] { animation: none; }

/* recipe E — option rows shared by menus, select lists, combobox options and palette results */
.sg-menu { display: flex; flex-direction: column; outline: none; }
.sg-menu-item { position: relative; display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: 36px; padding: 6px 12px; box-sizing: border-box; margin: 0;
  border: 0; border-radius: var(--radius-xs); background: transparent; color: var(--ink); font: inherit; font-size: 15px; line-height: 20px; text-align: start;
  cursor: pointer; user-select: none; -webkit-user-select: none; outline: none;
  transition: background-color var(--duration-instant) var(--ease-liquid); }
.sg-menu-item[data-active] { background: var(--state-hover); }
.sg-menu-item:active:not([aria-disabled="true"]) { background: var(--state-pressed); }
.sg-menu-item[aria-selected="true"], .sg-menu-item[aria-checked="true"] { font-weight: 500; }
.sg-menu[aria-multiselectable="true"] .sg-menu-item[aria-selected="true"] { background: var(--state-selected); }
.sg-menu[aria-multiselectable="true"] .sg-menu-item[aria-selected="true"][data-active] { background: linear-gradient(var(--state-hover), var(--state-hover)), var(--state-selected); }
.sg-menu-item[aria-disabled="true"] { opacity: var(--disabled); cursor: not-allowed; }
.sg-menu-item.is-danger, .sg-menu-item.is-danger .sg-menu-icon { color: var(--status-bad); }
.sg-menu-icon { width: 16px; height: 16px; flex: none; color: var(--ink-2); }
.sg-menu-text { flex: 1; min-width: 0; display: grid; }
.sg-menu-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-menu-desc { font-size: 13px; line-height: 18px; font-weight: 400; color: var(--ink-2); }
.sg-menu-check { width: 16px; height: 16px; flex: none; margin-inline-start: auto; color: var(--ink); visibility: hidden; }
.sg-menu-item[aria-selected="true"] .sg-menu-check, .sg-menu-item[aria-checked="true"] .sg-menu-check { visibility: visible; }
.sg-menu-end { margin-inline-start: auto; display: inline-flex; align-items: center; gap: var(--space-1); color: var(--ink-2); }
.sg-menu-end .sg-icon { width: 16px; height: 16px; }
.sg-menu-sep { flex: none; height: 1px; margin: 4px 0; border: 0; background: var(--line); }
.sg-menu-label { padding: 8px 12px 4px; font-size: 12px; line-height: 16px; font-weight: 400; color: var(--ink-2); }
.sg-menu-kbd { margin-inline-start: auto; padding-inline-start: var(--space-4); display: inline-flex; align-items: center; gap: 2px; flex: none; color: var(--ink-2); }
.sg-menu--sm .sg-menu-item { min-height: 32px; padding-top: 4px; padding-bottom: 4px; font-size: 14px; }

/* keycap: Geist Mono 11, 20 high, half of radius-xs, glass-strong + line + a 1px bottom edge */
.sg-kbd { display: inline-grid; place-items: center; box-sizing: border-box; min-width: 20px; height: 20px; padding: 0 5px; margin: 0;
  border-radius: calc(var(--radius-xs) / 2); border: 1px solid var(--line); background: var(--glass-strong); box-shadow: inset 0 -1px 0 var(--line);
  font-family: var(--font-mono); font-size: 11px; line-height: 1; font-weight: 500; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Geist Mono draws ⌘ ⇧ ⌥ at about half the letter height; the platform UI font draws them at letter size */
.sg-kbd[data-sym] { font-family: system-ui, -apple-system, "Segoe UI Symbol", sans-serif; font-weight: 400; }

/* recipe A shell used outside TextField (FieldBox): size, invalid and disabled live on the box itself */
.sg-field-box.sg-field-box--sm { height: var(--control-sm); padding: 0 12px; }
.sg-field-box--sm .sg-field-input { font-size: 14px; }
.sg-field-box.is-invalid { border-color: var(--status-bad); }
.sg-field-box.is-invalid:focus-within { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--status-bad); }
.sg-field-box.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-field.is-disabled .sg-field-box.is-disabled { opacity: 1; }
.sg-field-box.is-disabled:hover { border-color: var(--line-strong); }
.sg-field-box.is-disabled .sg-field-input { cursor: not-allowed; }
button.sg-field-box { width: 100%; margin: 0; font: inherit; font-size: 15px; text-align: start; cursor: pointer; }
button.sg-field-box.sg-field-box--sm { font-size: 14px; }
.sg-field-box[aria-expanded="true"] { border-color: var(--ink); }
.sg-field-box.sg-field-box--multi { height: auto; min-height: var(--control-md); align-items: flex-start; padding-top: 10px; padding-bottom: 10px; }
.sg-field-box--multi .sg-field-input { height: auto; line-height: 22px; resize: none; }
.sg-field-box.sg-field-box--multi.sg-field-box--sm { min-height: var(--control-sm); padding-top: 5px; padding-bottom: 5px; }
.sg-field-box--multi.sg-field-box--sm .sg-field-input { line-height: 20px; }

@media (prefers-reduced-motion: reduce) {
  .sg-overlay[data-state="open"] { animation-name: sg-ov-fade; }
  .sg-overlay[data-state="closed"] { animation-name: sg-ov-fade-out; }
  .sg-menu-item { transition-property: background-color, color, opacity; }
}
@media (pointer: coarse) {
  .sg-menu-item, .sg-menu--sm .sg-menu-item { min-height: 44px; }
  /* a 32px shell outside a Field sm (Select without a label, Pagination's page size): same 6px reach above and below as core's .sg-field--sm rule */
  .sg-field-box--sm::before, .sg-field-box--sm::after { content: ""; position: absolute; left: -1px; right: -1px; height: 6px; }
  .sg-field-box--sm::before { top: -7px; }
  .sg-field-box--sm::after { bottom: -7px; }
}

/* ---------- Chinese typography (shared layer, T lane) ----------
 * Font families switch in tokens.css: under [lang|="zh"] every --font-* starts with the zh punctuation face,
 * so “ ” ‘ ’ — … use Chinese glyphs while Latin, digits and · stay Urbanist. This file adds the text rules.
 * Every rule is zero-specificity (:where) so components and pages can override it, and every property is one
 * that older browsers simply ignore (support noted per line; checked in Chrome 156). */

/* Set once at the language boundary (html lang="zh-CN", or any element with lang="zh-*"); children inherit,
 * so a component that sets one of these on its own root keeps it. */
:where([lang|="zh"]) {
  line-break: strict;              /* no line may start with 、。，：；！？」） or end with 「（ — all engines */
  text-spacing-trim: trim-start;   /* full-width opening punctuation is set half-width at every line start (first line too), adjacent pairs collapse — Chrome 123+ only */
  text-autospace: normal;          /* 1/8 em between hanzi and Latin/digits when the author left no space; a typed space is not doubled — Chrome 140+, Safari 18.4+, Firefox 145+ */
  font-synthesis-style: none;      /* never fake an oblique for Chinese — Chrome 97+, Safari 16.4+, Firefox 111+ */
}
/* Latin islands inside Chinese text (lang="en" …) may slant again; the other three rules do nothing to Latin text */
:where([lang]:not([lang|="zh"])) { font-synthesis-style: auto; }

/* No italics in Chinese: these elements stay upright; <em> gets 着重号 — a dot under each character (clreq).
 * The dot is U+2022 drawn from the zh punctuation face (PingFang • = 0.33 em, so the mark is ~2.5 px at 15 px);
 * it needs line-height ≥ 1.6 (body 15/24, prose 17/30). In caption/label text use weight 500 instead of <em>.
 * Stronger emphasis is weight: <strong>/<b> keep the browser's bolder (PingFang → Semibold, Shy Glass Hei → Bold). */
:where(em, i, cite, dfn, var, address):lang(zh) { font-style: normal; }
:where(em):lang(zh) {
  -webkit-text-emphasis: filled dot; text-emphasis: filled dot;
  -webkit-text-emphasis-position: under right; text-emphasis-position: under right;
}
@supports not ((text-emphasis: filled dot) or (-webkit-text-emphasis: filled dot)) {
  :where(em):lang(zh) { font-weight: 500; }
}

/* Paragraphs: avoid a last line holding one or two characters (孤字) — Chrome 130+, Safari 26+, not Firefox (caniuse, 2026-10) */
:where(p, li, dd, blockquote, figcaption, .body, .body-sm, .prose):lang(zh) { text-wrap-style: pretty; }

/* Component text sets its own pixel line-heights (12/16, 13/18 …), which are tight for Chinese. In Chinese the system's own scale is caption 12 / 18, body-sm 13 / 20 and label 13 / 20 (tokens.css):
 * helper and error lines are 12 px → 18; descriptions and 13 / 500 field labels are 13 px → 20. One-line chips, pills and cells with a fixed height are left alone.
 * Specificity is (0,2,0) on purpose: it has to beat the single-class rule the component wrote. */
:is(.sg-field-hint, .sg-field-error, .sg-menu-label, .sg-card-sub, .sg-stat-label):lang(zh) { line-height: 18px; }
:is(.sg-field-label, .sg-menu-desc, .sg-listitem-desc, .sg-empty-desc, .sg-check-hint, .sg-radio-hint, .sg-cmd-desc, .sg-file-error, .sg-file-state, .sg-drop-rule, .sg-cb-empty-hint, .sg-timeline-desc, .sg-list-footer):lang(zh) { line-height: 20px; }
/* the compact Timeline sets its description in 12 px */
.sg-timeline--sm .sg-timeline-desc:lang(zh) { line-height: 18px; }
/* rows with a description keep the heights the READMEs give: an option row 50 (5 + 20 + 20 + 5; sm 46), a List row 56 (7 + 22 + 20 + 7) */
.sg-menu-item:lang(zh):has(> .sg-menu-text > .sg-menu-desc) { padding-block: 5px; }
.sg-menu--sm .sg-menu-item:lang(zh):has(> .sg-menu-text > .sg-menu-desc) { padding-block: 3px; }
.sg-listitem-main:lang(zh):has(.sg-listitem-desc) { padding-block: 7px; }

/* Nothing here moves or is clickable: the two required tail sections are intentionally empty. */
@media (prefers-reduced-motion: reduce) { }
@media (pointer: coarse) { }

/* ---------- Accordion: rows separated by a 1px line; the panel grows with grid-template-rows (0fr → 1fr) ---------- */
.sg-accordion { --acc-px: 0px; display: block; color: var(--ink); font-size: 15px; line-height: 22px; }
.sg-accordion--surface { --acc-px: var(--space-4); overflow: hidden; border-radius: var(--radius-md); background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4); }
.sg-accordion-item + .sg-accordion-item { border-top: 1px solid var(--line); }
.sg-accordion-heading { margin: 0; font: inherit; }
.sg-accordion-trigger { display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: var(--row-md); box-sizing: border-box; margin: 0; padding: 12px var(--acc-px); border: 0; border-radius: 0; background: transparent;
  color: var(--ink); font: inherit; font-size: 15px; line-height: 22px; font-weight: 500; text-align: start; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--duration-instant) var(--ease-liquid); }
/* flat rows: the hover wash bleeds 12px past the text edge, the text itself stays on the page's left line */
.sg-accordion:not(.sg-accordion--surface) .sg-accordion-trigger { width: calc(100% + 24px); margin-inline: -12px; padding-inline: 12px; border-radius: var(--radius-xs); }
.sg-accordion-trigger:not(:disabled):hover { background: var(--state-hover); }
.sg-accordion-trigger:not(:disabled):active { background: var(--state-pressed); }
.sg-accordion-trigger:disabled { opacity: var(--disabled); cursor: not-allowed; }
/* inside a clipped surface the outer ring would be cut off: draw it inward */
.sg-accordion--surface .sg-accordion-trigger:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring), inset 0 0 0 4px var(--focus-halo); }
.sg-accordion-icon { width: 18px; height: 18px; color: var(--ink-2); }
.sg-accordion-title { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.sg-accordion-extra { flex: none; font-size: 13px; line-height: 18px; font-weight: 400; color: var(--ink-2); white-space: nowrap; }
.sg-accordion-chev { width: 18px; height: 18px; color: var(--ink-2); transition: transform calc(var(--duration-smooth) * 2 / 3) var(--ease-exit); }
.sg-accordion-item.is-open > .sg-accordion-heading .sg-accordion-chev { transform: rotate(180deg); transition: transform var(--duration-smooth) var(--ease-spring-soft); }

/* closed: 2/3 of the time, ease-exit, and the panel leaves the accessibility tree and the tab order once it has finished closing */
.sg-accordion-panel { display: grid; grid-template-rows: 0fr; visibility: hidden;
  transition: grid-template-rows calc(var(--duration-smooth) * 2 / 3) var(--ease-exit), visibility 0s linear calc(var(--duration-smooth) * 2 / 3); }
.sg-accordion-item.is-open > .sg-accordion-panel { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows var(--duration-smooth) var(--ease-spring-soft), visibility 0s; }
/* the clip has 6px of room each side so a focus ring on a control inside the panel is not cut */
.sg-accordion-clip { min-height: 0; overflow: hidden; margin-inline: -6px; padding-inline: 6px; }
.sg-accordion-body { padding: 0 var(--acc-px) var(--space-4); color: var(--ink-2); opacity: 0; transition: opacity calc(var(--duration-base) * 2 / 3) var(--ease-exit); }
.sg-accordion-item.is-open .sg-accordion-body { opacity: 1; transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-accordion-body > :first-child { margin-top: 0; }
.sg-accordion-body > :last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) {
  .sg-accordion-panel, .sg-accordion-item.is-open > .sg-accordion-panel { transition: visibility 0s; }
  .sg-accordion-chev, .sg-accordion-item.is-open > .sg-accordion-heading .sg-accordion-chev { transition: none; }
  .sg-accordion-body, .sg-accordion-item.is-open .sg-accordion-body { transition-property: opacity; transition-duration: var(--duration-quick); transition-timing-function: linear; }
}
@media (pointer: coarse) {
  /* rows are 52px tall already: nothing here is smaller than a finger */
  .sg-accordion-trigger { min-height: var(--row-md); }
}

/* ---------- ActionSheet: a transparent holder with two recipe-D cards (the actions, and the cancel block 8px below), pinned to the bottom of the modal layer ---------- */
/* the layer from Dialog.css (.sg-modal, scrim and the nudge come from there): 12px left, right and bottom, and the home-indicator inset on top of the bottom 12px */
.sg-modal.sg-modal--sheet { align-items: flex-end; justify-content: center;
  padding: max(var(--space-3), env(safe-area-inset-top, 0px)) max(var(--space-3), env(safe-area-inset-right, 0px)) calc(var(--space-3) + env(safe-area-inset-bottom, 0px)) max(var(--space-3), env(safe-area-inset-left, 0px)); }

/* the holder: no glass of its own (the cards carry it), so it slides as one piece */
.sg-overlay.sg-modal-panel.sg-actsheet { width: min(420px, 100%); max-height: 100%; display: flex; flex-direction: column; padding: 0; overflow: visible; border: 0; border-radius: 0;
  background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; transform-origin: 50% 100%; font-size: 15px; }
.sg-actsheet-drag { display: flex; flex-direction: column; gap: 8px; min-height: 0; max-height: 100%; transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-actsheet-drag.is-dragging { transition: none; }

/* in: slides up on the soft spring (it may settle a hair past its place); out: 2/3 of that, ease-exit. Only transform moves, so the cards' own backdrop blur is never put behind a fading parent. */
.sg-modal--sheet .sg-overlay.sg-modal-panel.sg-actsheet[data-state="open"] { animation: sg-actsheet-in var(--duration-smooth) var(--ease-spring-soft) both; }
.sg-modal--sheet .sg-overlay.sg-modal-panel.sg-actsheet[data-state="closed"] { animation: sg-actsheet-out calc(var(--duration-smooth) * 2 / 3) var(--ease-exit) both; }
.sg-modal--sheet .sg-overlay.sg-modal-panel.sg-actsheet[data-instant][data-state="open"] { animation: none; }
@keyframes sg-actsheet-in { from { transform: translateY(calc(100% + var(--space-3) + env(safe-area-inset-bottom, 0px))); } }
@keyframes sg-actsheet-out { to { transform: translateY(calc(100% + var(--space-3) + env(safe-area-inset-bottom, 0px))); } }

/* recipe D at radius-lg */
.sg-actsheet-card { box-sizing: border-box; background: var(--glass-overlay); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: var(--shadow-float);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4); color: var(--ink); }
.sg-actsheet-main { display: flex; flex-direction: column; min-height: 0; flex: 0 1 auto; overflow: hidden; }

/* the grip: 36 x 4, and a draggable band of 20px around it */
.sg-actsheet-grip { flex: none; display: flex; justify-content: center; padding: 8px 0 8px; touch-action: none; cursor: grab; }
.sg-actsheet-grip i { width: 36px; height: 4px; border-radius: var(--radius-pill); background: var(--line-strong); }
.sg-actsheet-drag.is-dragging .sg-actsheet-grip { cursor: grabbing; }

/* title 13 / 500 ink-2, description 12 ink-2, centred */
.sg-actsheet-head { flex: none; padding: 0 var(--space-4) 12px; text-align: center; touch-action: none; }
.sg-actsheet-head.has-list { border-bottom: 1px solid var(--line); }
.sg-actsheet-title { margin: 0; font-size: 13px; line-height: 18px; font-weight: 500; letter-spacing: normal; color: var(--ink-2); overflow-wrap: anywhere; }
.sg-actsheet-desc-top { margin: 2px 0 0; font-size: 12px; line-height: 16px; color: var(--ink-2); overflow-wrap: anywhere; }
.sg-actsheet-head:lang(zh) .sg-actsheet-title { line-height: 20px; }
.sg-actsheet-head:lang(zh) .sg-actsheet-desc-top { line-height: 18px; }

/* the list scrolls when there are more actions than room */
.sg-actsheet-list { flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; outline: none; }
.sg-actsheet-list::-webkit-scrollbar { display: none; }
.sg-actsheet-group + .sg-actsheet-group { border-top: 8px solid var(--state-hover); }

/* an action: row-md (52) high, 17 / 400. Centred without an icon, left-aligned with a 20px icon. */
.sg-actsheet-act { position: relative; display: flex; align-items: center; justify-content: center; gap: var(--space-3); width: 100%; min-height: var(--row-md); box-sizing: border-box; margin: 0; padding: 8px var(--space-4);
  border: 0; border-top: 1px solid var(--line); border-radius: 0; background: transparent; color: var(--ink); font: inherit; font-size: 17px; line-height: 24px; font-weight: 400; text-align: center; cursor: pointer;
  outline: none; -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none;
  transition: background-color var(--duration-instant) var(--ease-liquid); }
.sg-actsheet-group:first-child > .sg-actsheet-act:first-child { border-top-color: transparent; }
.sg-actsheet-head.has-list + .sg-actsheet-list .sg-actsheet-group:first-child > .sg-actsheet-act:first-child { border-top-color: transparent; }
.sg-actsheet-group + .sg-actsheet-group > .sg-actsheet-act:first-child { border-top-color: transparent; }
.sg-actsheet-act.has-icon { justify-content: flex-start; padding-inline: var(--space-5); text-align: start; }
.sg-actsheet-ic { flex: none; display: inline-flex; width: 20px; height: 20px; color: var(--ink-2); }
.sg-actsheet-ic .sg-icon { width: 20px; height: 20px; }
.sg-actsheet-txt { min-width: 0; display: grid; justify-items: inherit; }
.sg-actsheet-act:not(.has-icon) .sg-actsheet-txt { justify-items: center; }
.sg-actsheet-lab { min-width: 0; overflow-wrap: anywhere; }
.sg-actsheet-desc { font-size: 13px; line-height: 18px; color: var(--ink-2); overflow-wrap: anywhere; }
.sg-actsheet-act.is-danger, .sg-actsheet-act.is-danger .sg-actsheet-ic { color: var(--status-bad); }
.sg-actsheet-act.is-disabled, .sg-actsheet-chan.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-actsheet-act.is-busy { cursor: progress; }
.sg-actsheet-dots { color: var(--ink-2); }
.sg-actsheet-act:active:not(.is-disabled) { background: var(--state-pressed); }
.sg-actsheet-act:focus-visible { border-radius: var(--radius-xs); box-shadow: inset 0 0 0 2px var(--focus-ring), inset 0 0 0 4px var(--focus-halo); }

/* channels (layout="grid"): a 52px glass circle with its name below, a row of 4 to 5; more than 5 scroll sideways and the next one peeks in.
   --sg-chan-w (set on the list from the longest row) is the cell width of every row, so the icons of two rows line up and a short row stays at the left */
.sg-actsheet-chans { display: flex; gap: 4px; padding: 14px var(--space-2) 12px; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; }
.sg-actsheet-chans::-webkit-scrollbar { display: none; }
.sg-actsheet-group.sg-actsheet-chans + .sg-actsheet-group.sg-actsheet-chans { border-top: 1px solid var(--line); }
.sg-actsheet-chan { flex: 0 0 var(--sg-chan-w, 25%); min-width: 60px; display: flex; flex-direction: column; align-items: center; gap: var(--space-2); box-sizing: border-box; margin: 0; padding: 0 2px; border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--ink); font: inherit; cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none; }
.sg-actsheet-chan-ic { display: grid; place-items: center; width: 52px; height: 52px; box-sizing: border-box; border-radius: var(--radius-pill); background: var(--glass); border: 1px solid var(--line);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); box-shadow: var(--shadow-glass); color: var(--ink);
  transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-actsheet-chan-ic .sg-icon { width: 24px; height: 24px; }
.sg-actsheet-chan-name { max-width: 100%; font-size: 12px; line-height: 16px; color: var(--ink); text-align: center; overflow-wrap: anywhere; }
.sg-actsheet-chan.is-danger .sg-actsheet-chan-ic, .sg-actsheet-chan.is-danger .sg-actsheet-chan-name { color: var(--status-bad); }
.sg-actsheet-chan:active:not(.is-disabled) .sg-actsheet-chan-ic { transform: scale(.92); }
.sg-actsheet-chan:focus-visible .sg-actsheet-chan-ic { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }

/* the cancel block: its own card, 52 high, 17 / 500 */
.sg-actsheet-cancel { flex: none; display: flex; align-items: center; justify-content: center; width: 100%; height: 52px; margin: 0; padding: 0 var(--space-4); font: inherit; font-size: 17px; line-height: 24px; font-weight: 500;
  cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-instant) var(--ease-liquid); }
.sg-actsheet-cancel:active { background: var(--state-pressed); }

/* toolbar mode: 52px row, cancel (ink-2) · title 15 / 500 · confirm (ink 500), then the content */
.sg-actsheet-bar { flex: none; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; min-height: 52px; padding: 0 var(--space-1); border-bottom: 1px solid var(--line); }
.sg-actsheet-barbtn { min-height: 40px; max-width: 100%; box-sizing: border-box; margin: 0; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-xs); background: none; font: inherit; font-size: 15px; line-height: 22px;
  cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-instant) var(--ease-liquid); }
.sg-actsheet-barbtn.is-cancel { justify-self: start; color: var(--ink-2); }
.sg-actsheet-barbtn.is-confirm { justify-self: end; color: var(--ink); font-weight: 500; }
.sg-actsheet-barbtn:active { background: var(--state-pressed); }
.sg-actsheet-bartitle { margin: 0; padding: 0 var(--space-2); min-width: 0; font-size: 15px; line-height: 22px; font-weight: 500; letter-spacing: normal; color: var(--ink); text-align: center; touch-action: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-actsheet-content { flex: 1 1 auto; min-height: 0; overflow: auto; overscroll-behavior: contain; padding: var(--space-2) var(--space-4) var(--space-4); }

@media (hover: hover) {
  .sg-actsheet-act:hover:not(.is-disabled), .sg-actsheet-act[data-active]:not(.is-disabled) { background: var(--state-hover); }
  .sg-actsheet-act:active:not(.is-disabled) { background: var(--state-pressed); }
  .sg-actsheet-chan:hover:not(.is-disabled) .sg-actsheet-chan-ic { transform: translateY(-1px); }
  .sg-actsheet-cancel:hover, .sg-actsheet-barbtn:hover { background: var(--state-hover); }
  .sg-actsheet-cancel:active, .sg-actsheet-barbtn:active { background: var(--state-pressed); }
}
.sg-actsheet-cancel:focus-visible, .sg-actsheet-barbtn:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-actsheet-barbtn:focus-visible { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  /* no slide, no follow-the-finger: the cards fade (each carries its own blur, so the fade goes on them and not on the holder) */
  .sg-modal--sheet .sg-overlay.sg-modal-panel.sg-actsheet[data-state="open"], .sg-modal--sheet .sg-overlay.sg-modal-panel.sg-actsheet[data-state="closed"] { animation: none; }
  .sg-modal--sheet .sg-actsheet[data-state="open"] .sg-actsheet-card { animation: sg-modal-fade var(--duration-base) var(--ease-liquid) both; }
  .sg-modal--sheet .sg-actsheet[data-state="closed"] .sg-actsheet-card { animation: sg-modal-fade-out calc(var(--duration-base) * 2 / 3) var(--ease-exit) both; }
  .sg-modal--sheet .sg-actsheet[data-instant][data-state="open"] .sg-actsheet-card { animation: none; }
  .sg-actsheet-drag { transition: none; }
  .sg-actsheet-grip { cursor: default; touch-action: auto; }
  .sg-actsheet-chan-ic, .sg-actsheet-chan:hover:not(.is-disabled) .sg-actsheet-chan-ic, .sg-actsheet-chan:active:not(.is-disabled) .sg-actsheet-chan-ic { transform: none; transition-property: none; }
}
@media (pointer: coarse) {
  /* the toolbar buttons are 40px high: the hit area reaches 44 above and below, the look stays */
  .sg-actsheet-barbtn { position: relative; }
  .sg-actsheet-barbtn::after { content: ""; position: absolute; left: 0; right: 0; top: -2px; bottom: -2px; }
  .sg-actsheet-barbtn.is-none::after { content: none; }
  /* a 28px grab band around the 4px grip */
  .sg-actsheet-grip { padding: 12px 0 12px; }
}
@media (max-width: 479px) {
  .sg-actsheet-chan { min-width: 56px; }
}

/* ---------- AgreementCheck: a Checkbox whose words are 13/20 ink-2 with the document names as Links (ink, 500); the words hang to the right of the box ---------- */
.sg-agree { display: grid; gap: 4px; min-width: 0; justify-items: start; }
.sg-agree-row { min-width: 0; max-width: 100%; }
.sg-agree .sg-check { font-size: 13px; line-height: 20px; color: var(--ink-2); min-height: 20px; }
.sg-agree .sg-check-box { margin-top: 0; }
.sg-agree .sg-check-input { top: 0; }
.sg-agree .sg-check-title { overflow-wrap: anywhere; }
.sg-agree .sg-agree-name, .sg-agree .sg-agree-doc { color: var(--ink); font-weight: 500; }
.sg-agree .sg-agree-doc.is-plain { text-decoration: none; }
.sg-agree--sm .sg-check { font-size: 12px; line-height: 18px; }
/* the problem, under the row, in line with the words (20px box + 12px gap) */
.sg-agree-err { margin: 0 0 0 32px; display: flex; align-items: flex-start; gap: 6px; font-size: 12px; line-height: 18px; color: var(--status-bad); }
.sg-agree-err .sg-icon { flex: none; margin-top: 2px; }
/* a reminder shakes the whole row once: 0 → 6 → -6 → 4 → -2 → 0 px in 320ms */
.sg-agree-row.is-shake { animation: sg-agree-shake 320ms var(--ease-liquid) both; }
@keyframes sg-agree-shake { 0% { transform: translateX(0); } 20% { transform: translateX(6px); } 40% { transform: translateX(-6px); } 60% { transform: translateX(4px); } 80% { transform: translateX(-2px); } 100% { transform: translateX(0); } }

@media (prefers-reduced-motion: reduce) {
  /* no shake: the box turns red and the sentence appears */
  .sg-agree-row.is-shake { animation: none; }
}
@media (pointer: coarse) {
  /* the whole row is at least 44px high (Checkbox's own touch rule); with 20px lines the words sit 12px from the top and bottom */
  .sg-agree .sg-check-text { padding-block: 12px; }
  .sg-agree .sg-check-input { top: 12px; }
  .sg-agree .sg-check-box { margin-top: 12px; }
  .sg-agree.sg-agree--sm .sg-check-text { padding-block: 13px; }
  .sg-agree.sg-agree--sm .sg-check-input { top: 12px; }
  .sg-agree.sg-agree--sm .sg-check-box { margin-top: 12px; }
}

/* ---------- Alert: recipe F surface (blur-md, line, shadow-glass, radius-md) on a flat mist-100 base: a glass-strong base is a see-through white in dark, and a wash over it turns grey. Tone = icon colour + a 10% wash; the outline stays the neutral line, so colour shows in two places, not three. ---------- */
.sg-alert { --tc: var(--ink-2); --tp: 10%; position: relative; box-sizing: border-box; display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-3); width: 100%; padding: 14px var(--space-4); border-radius: var(--radius-md);
  color: var(--ink); background: color-mix(in srgb, var(--tc) var(--tp), var(--mist-100)); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4); }
.sg-alert.is-info { --tp: 0%; }
.sg-alert.is-success { --tc: var(--status-good); }
.sg-alert.is-warning { --tc: var(--status-warn); }
.sg-alert.is-error { --tc: var(--status-bad); }
.sg-alert .sg-alert-icon { margin-top: 2px; color: var(--tc); }
.sg-alert-body { flex: 1 1 200px; min-width: 0; }
.sg-alert .sg-alert-title { font-weight: 500; color: var(--ink); }
.sg-alert .sg-alert-desc { margin-top: 2px; color: var(--ink-2); }
.sg-alert .sg-alert-text { color: var(--ink); }
/* when it wraps, the action drops under the text (32px = icon + gap); when it fits it sits at the end of the row */
.sg-alert-action { flex: none; display: flex; align-items: center; gap: var(--space-2); margin-inline-start: 32px; align-self: center; }
.sg-alert.is-plain .sg-alert-action { align-self: center; }
/* a one-line message beside a 32px button: centre the whole row on the button instead of hanging the text from the top */
.sg-alert.is-plain.has-action { align-items: center; }
.sg-alert.is-plain.has-action .sg-alert-icon { margin-top: 0; }
.sg-alert.has-close { padding-inline-end: 44px; }
.sg-alert .sg-alert-close { position: absolute; top: 12px; right: 10px; }
.sg-alert--banner { padding: 10px var(--space-6); border-radius: 0; border-inline-width: 0; box-shadow: none; }
.sg-alert--banner.has-close { padding-inline-end: 52px; }
.sg-alert--banner .sg-alert-close { top: 50%; right: 18px; translate: 0 -50%; }

/* closing: the row folds up (grid-template-rows 1fr → 0fr) while it fades, 2/3 of duration-smooth; opening after first paint unfolds the same way */
.sg-alert-wrap { display: grid; grid-template-rows: 1fr; }
.sg-alert-wrap > .sg-alert { min-height: 0; }
.sg-alert-wrap[data-state="closed"] { grid-template-rows: 0fr; opacity: 0; pointer-events: none;
  transition: grid-template-rows calc(var(--duration-smooth) * 2 / 3) var(--ease-exit), opacity calc(var(--duration-smooth) * 2 / 3) var(--ease-exit); }
.sg-alert-wrap[data-state="closed"] > .sg-alert { overflow: hidden; }
.sg-alert-wrap.is-anim[data-state="open"] { animation: sg-alert-unfold var(--duration-smooth) var(--ease-spring-soft) both; }
@keyframes sg-alert-unfold { from { grid-template-rows: 0fr; opacity: 0; } }
@keyframes sg-alert-fade { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .sg-alert-wrap[data-state="closed"] { transition-property: opacity; grid-template-rows: 1fr; }
  .sg-alert-wrap.is-anim[data-state="open"] { animation-name: sg-alert-fade; }
}
@media (pointer: coarse) {
  /* the close button is the IconButton xs: core already gives it a 44px reach; keep it pinned at the corner */
  .sg-alert .sg-alert-close { position: absolute; }
  .sg-alert--banner .sg-alert-close { position: absolute; }
}

/* ---------- AlertDialog (structure, motion and the nudge come from Dialog.css) ---------- */
/* the title is the 17/24 `heading` style (set in the markup); the description is the same 15px ink-2 as in Dialog (rule in Dialog.css) */
.sg-dialog--alert .sg-modal-body { padding-top: var(--space-3); }

@media (prefers-reduced-motion: reduce) {
  .sg-dialog--alert .sg-modal-foot .sg-btn { transition-property: background-color, box-shadow; }
}
@media (pointer: coarse) {
  /* the two actions are 44px buttons already; keep them apart so a thumb does not hit the wrong one */
  .sg-dialog--alert .sg-modal-foot { gap: var(--space-3); }
}

/* ---------- AppShell and the layout pieces (Container, Stack, Grid, GridItem) ----------
   Breakpoints are 0 / 640 / 1024 / 1440. Each responsive value arrives as four custom properties on the element (--sg-cols-0 … --sg-cols-1440);
   the @media rules below pick one, so the first paint is right and no script watches the window. */

/* ---- Container: the page column, centred; side padding follows the width ---- */
.sg-container { --sg-cpx: var(--space-4); --sg-cw: 1200px; box-sizing: border-box; width: 100%; margin-inline: auto; padding-inline: var(--sg-cpx); max-width: calc(var(--sg-cw) + 2 * var(--sg-cpx)); }
.sg-container--sm { --sg-cw: 640px; }
.sg-container--md { --sg-cw: 960px; }
.sg-container--lg { --sg-cw: 1200px; }
.sg-container--xl { --sg-cw: 1440px; }
.sg-container--full { max-width: none; }
.sg-container.is-flush { --sg-cpx: 0px; }
@media (min-width: 640px) { .sg-container:not(.is-flush) { --sg-cpx: var(--space-6); } }
@media (min-width: 1024px) { .sg-container:not(.is-flush) { --sg-cpx: var(--space-8); } }
@media (min-width: 1440px) { .sg-container:not(.is-flush) { --sg-cpx: var(--space-12); } }

/* ---- Stack: one direction, a gap from the space scale ---- */
.sg-stack { display: flex; flex-direction: var(--sg-sd-0); gap: var(--sg-sg-0); min-width: 0; }
@media (min-width: 640px) { .sg-stack { flex-direction: var(--sg-sd-640); gap: var(--sg-sg-640); } }
@media (min-width: 1024px) { .sg-stack { flex-direction: var(--sg-sd-1024); gap: var(--sg-sg-1024); } }
@media (min-width: 1440px) { .sg-stack { flex-direction: var(--sg-sd-1440); gap: var(--sg-sg-1440); } }
.sg-stack.is-a-start { align-items: flex-start; }
.sg-stack.is-a-center { align-items: center; }
.sg-stack.is-a-end { align-items: flex-end; }
.sg-stack.is-a-stretch { align-items: stretch; }
.sg-stack.is-a-baseline { align-items: baseline; }
.sg-stack.is-j-start { justify-content: flex-start; }
.sg-stack.is-j-center { justify-content: center; }
.sg-stack.is-j-end { justify-content: flex-end; }
.sg-stack.is-j-between { justify-content: space-between; }
.sg-stack.is-wrap { flex-wrap: wrap; }
/* the dividers between children: a vertical one stretches to the height of the row */
.sg-stack > .sg-divider--v { align-self: stretch; height: auto; min-height: 1em; }
.sg-stack.is-a-baseline > .sg-divider--v { align-self: center; height: 1em; }
.sg-stack-sep { display: contents; }
.sg-stack-sep > .sg-divider--h { display: var(--sg-seph-0); }
.sg-stack-sep > .sg-divider--v { display: var(--sg-sepv-0); align-self: stretch; height: auto; min-height: 1em; }
@media (min-width: 640px) { .sg-stack-sep > .sg-divider--h { display: var(--sg-seph-640); } .sg-stack-sep > .sg-divider--v { display: var(--sg-sepv-640); } }
@media (min-width: 1024px) { .sg-stack-sep > .sg-divider--h { display: var(--sg-seph-1024); } .sg-stack-sep > .sg-divider--v { display: var(--sg-sepv-1024); } }
@media (min-width: 1440px) { .sg-stack-sep > .sg-divider--h { display: var(--sg-seph-1440); } .sg-stack-sep > .sg-divider--v { display: var(--sg-sepv-1440); } }

/* ---- Grid and GridItem: columns (a number, tracks, or both by width), a gap, spans that never make columns of their own ---- */
.sg-grid { display: grid; grid-template-columns: var(--sg-cols-0); gap: var(--sg-gap-0); min-width: 0; }
.sg-grid.is-dense { grid-auto-flow: dense; }
@media (min-width: 640px) { .sg-grid { grid-template-columns: var(--sg-cols-640); gap: var(--sg-gap-640); } }
@media (min-width: 1024px) { .sg-grid { grid-template-columns: var(--sg-cols-1024); gap: var(--sg-gap-1024); } }
@media (min-width: 1440px) { .sg-grid { grid-template-columns: var(--sg-cols-1440); gap: var(--sg-gap-1440); } }
.sg-griditem { min-width: 0; }
.sg-griditem.has-span { grid-column: var(--sg-gc-0); }
@media (min-width: 640px) { .sg-griditem.has-span { grid-column: var(--sg-gc-640); } }
@media (min-width: 1024px) { .sg-griditem.has-span { grid-column: var(--sg-gc-1024); } }
@media (min-width: 1440px) { .sg-griditem.has-span { grid-column: var(--sg-gc-1440); } }

/* ---- AppShell ---- */
/* 0 → 1 while an auto-hide header slides away: the things that stick below the header (the header-first sidebar, the right column) follow it up on the same curve */
@property --sg-shell-hide { syntax: "<number>"; inherits: true; initial-value: 0; }
.sg-shell { --sg-shell-px: var(--space-4); --sg-shell-top: calc(var(--sg-shell-header-h, 0px) * (1 - var(--sg-shell-hide))); position: relative; isolation: isolate; box-sizing: border-box; color: var(--ink);
  transition: --sg-shell-hide var(--duration-base) var(--ease-liquid); }
@media (min-width: 640px) { .sg-shell { --sg-shell-px: var(--space-6); } }
@media (min-width: 1024px) { .sg-shell { --sg-shell-px: var(--space-8); } }
@media (min-width: 1440px) { .sg-shell { --sg-shell-px: var(--space-12); } }
/* the page background: the preview stage's recipe (mist with an indigo and a teal glow), fixed to the window so glass has something to show through */
.sg-shell.has-backdrop::before { content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(40% 60% at 15% 20%, color-mix(in srgb, var(--glow-indigo) 30%, transparent), transparent 70%), radial-gradient(35% 50% at 85% 80%, color-mix(in srgb, var(--glow-teal) 30%, transparent), transparent 70%), var(--mist-000); }

/* the skip link: first in the tab order, out of sight until it takes focus, then an ink sm button in the top-left corner */
.sg-shell-skip:not(:focus) { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.sg-shell-skip:focus { position: fixed; top: var(--space-2); left: var(--space-2); z-index: calc(var(--z-sticky) + 2); }

/* sidebar-first: the sidebar runs the full height of the window, header and content sit to its right */
.sg-shell--sidebar-first { display: flex; align-items: stretch; min-height: 100vh; min-height: 100dvh; }
.sg-shell-side { position: sticky; top: 0; align-self: flex-start; flex: none; z-index: calc(var(--z-sticky) - 1); height: 100vh; height: 100dvh; }
.sg-shell-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; }
/* header-first: the header spans the top; below it the sidebar and the column; the sidebar sticks under the header */
.sg-shell--header-first { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }
.sg-shell-row { flex: 1 0 auto; display: flex; align-items: stretch; min-width: 0; }
.sg-shell--header-first .sg-shell-side { top: var(--sg-shell-top); height: calc(100vh - var(--sg-shell-top)); height: calc(100dvh - var(--sg-shell-top)); }
/* the main area scrolls by itself: the shell is exactly the window, only the column moves */
.sg-shell.is-scroll-main { height: 100vh; height: 100dvh; min-height: 0; overflow: hidden; }
.sg-shell.is-scroll-main .sg-shell-side { position: static; height: 100%; }
.sg-shell.is-scroll-main .sg-shell-col { min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.sg-shell.is-scroll-main.sg-shell--header-first .sg-shell-row { flex: 1 1 0; min-height: 0; }

/* the header slot: sticks (or not); once the page has scrolled the background is overlay glass; auto-hide slides it away on the way down */
.sg-shell-header { position: relative; isolation: isolate; flex: none; z-index: var(--z-sticky); transition: transform var(--duration-base) var(--ease-liquid); }
.sg-shell-header.is-sticky { position: sticky; top: 0; }
.sg-shell-header::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: 0; background: var(--glass-overlay); border-bottom: 1px solid var(--line);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4); transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-shell-header[data-stuck]::before { opacity: 1; }
.sg-shell-header[data-hidden] { transform: translateY(-100%); }
.sg-shell-header[data-hidden]:focus-within { transform: none; }

/* the content: page margins that follow the width (space-4 to space-12), main and the right column 300px wide with a space-4 gap */
.sg-shell-content { box-sizing: border-box; flex: 1 0 auto; width: 100%; display: grid; grid-template-columns: minmax(0, 1fr); align-items: start; gap: var(--space-4); padding: var(--space-4) var(--sg-shell-px) var(--space-8); }
.sg-shell-content.has-max { max-width: calc(var(--sg-content-max) + 2 * var(--sg-shell-px)); margin-inline: auto; }
.sg-shell-content.has-aside { grid-template-columns: minmax(0, 1fr) 300px; }
.sg-shell.is-narrow .sg-shell-content { gap: var(--space-3); }
.sg-shell.is-narrow .sg-shell-content.has-aside { grid-template-columns: minmax(0, 1fr); }
.sg-shell-main { min-width: 0; outline: none; }
.sg-shell-aside { min-width: 0; position: sticky; top: calc(var(--sg-shell-top) + var(--space-4)); }
.sg-shell.is-narrow .sg-shell-aside { position: static; }
.sg-shell-footer { flex: none; }
/* a phone's bottom bar floats over the page's last 88px (TabBar writes the exact height to --sg-bottom-offset): the room goes at the very end, under the footer, not under the main area.
   When the main area scrolls by itself the room is the end of that scroll */
.sg-shell.is-narrow.has-bottom { padding-bottom: var(--sg-bottom-offset, 88px); }
.sg-shell.is-narrow.has-bottom.is-scroll-main { padding-bottom: 0; }
.sg-shell.is-narrow.has-bottom.is-scroll-main .sg-shell-col { padding-bottom: var(--sg-bottom-offset, 88px); }

/* a NavRail in the sidebar slot floats 12px from the window's top, bottom and left edge, the same as a glass Sidebar */
.sg-shell-side > .sg-navrail { height: calc(100% - var(--space-6)); margin: var(--space-3) 0 var(--space-3) var(--space-3); }

/* the sidebar in the narrow drawer: the drawer is the glass, the sidebar fills it without a margin of its own and its foot (the account) sits at the bottom of the drawer */
.sg-overlay.sg-modal-panel.sg-shell-drawer { --sg-modal-w: 320px; }
.sg-overlay.sg-modal-panel.sg-shell-drawer .sg-modal-body { display: flex; flex-direction: column; padding: 0; border-color: transparent; }
.sg-overlay.sg-modal-panel.sg-shell-drawer .sg-modal-inner { flex: 1 0 auto; display: flex; flex-direction: column; }

@media (prefers-reduced-motion: reduce) {
  /* the header never slides away; the glass only fades */
  .sg-shell { transition: none; }
  .sg-shell-header { transition: none; }
  .sg-shell-header[data-hidden] { transform: none; }
  .sg-shell-header::before { transition-duration: var(--duration-instant); }
}
@media (pointer: coarse) {
  /* the skip link is an sm button: it gets its 44px reach from core; layout pieces have nothing to tap */
  .sg-shell-skip:focus { top: var(--space-3); left: var(--space-3); }
}

/* ---------- Avatar: a circle at 24 / 32 / 40 / 56. Colour from the four pulse tokens, text on-pulse; a photo covers the text when it has loaded ---------- */
.sg-avatar { --av: 40px; --av-bg: var(--pulse-indigo); --av-fg: var(--on-pulse); --dz: 8px;
  position: relative; display: inline-block; flex: none; vertical-align: middle; width: var(--av); height: var(--av); box-sizing: border-box; margin: 0; padding: 0; border: 0; border-radius: 50%;
  background: none; color: var(--av-fg); font: inherit; font-size: 15px; font-weight: 500; line-height: 1; letter-spacing: 0; text-align: center; user-select: none; -webkit-user-select: none; }
.sg-avatar--24 { --av: 24px; --dz: 6px; font-size: 12px; }
.sg-avatar--32 { --av: 32px; --dz: 6px; font-size: 13px; }
.sg-avatar--40 { --av: 40px; --dz: 8px; font-size: 15px; }
.sg-avatar--56 { --av: 56px; --dz: 10px; font-size: 20px; }
.sg-avatar--magenta { --av-bg: var(--pulse-magenta); }
.sg-avatar--indigo { --av-bg: var(--pulse-indigo); }
.sg-avatar--ember { --av-bg: var(--pulse-ember); }
.sg-avatar--teal { --av-bg: var(--pulse-teal); }
.sg-avatar--neutral { --av-bg: var(--glass-strong); --av-fg: var(--ink); }
/* the face clips the photo to the circle; the status dot sits outside it, so it is not clipped */
.sg-avatar-face { position: absolute; inset: 0; display: grid; place-items: center; overflow: hidden; border-radius: 50%; background: var(--av-bg);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--av-fg) 14%, transparent); }
.sg-avatar--neutral .sg-avatar-face { box-shadow: inset 0 0 0 1px var(--line); -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-avatar-text { position: relative; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sg-avatar-icon { width: 50%; height: 50%; opacity: .85; }
.sg-avatar-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-avatar-img.is-loaded { opacity: 1; }
/* status: StatusLight (shape + colour) on the lower-right of the circle, ringed in the page colour so it reads on a photo */
.sg-avatar-status { position: absolute; right: calc(var(--av) * .146 - var(--dz) / 2); bottom: calc(var(--av) * .146 - var(--dz) / 2); width: var(--dz); height: var(--dz); display: grid; place-items: center; border-radius: 50%;
  box-shadow: 0 0 0 2px var(--sg-avatar-ring, var(--mist-000)); background: var(--sg-avatar-ring, var(--mist-000)); }
.sg-avatar-status .sg-light { display: block; }
button.sg-avatar { cursor: pointer; transition: transform var(--duration-quick) var(--ease-liquid); }
button.sg-avatar:active { transform: scale(.94); }

/* group: -8px overlap, 2px ring in the page colour, the first member on top so the first name stays readable */
.sg-avatars { display: inline-flex; align-items: center; vertical-align: middle; isolation: isolate; }
.sg-avatars-item { position: relative; display: inline-flex; flex: none; border-radius: 50%; box-shadow: 0 0 0 2px var(--sg-avatar-ring, var(--mist-000)); background: var(--sg-avatar-ring, var(--mist-000)); }
.sg-avatars-item + .sg-avatars-item { margin-inline-start: -8px; }
.sg-avatars-item .sg-avatar-status { display: none; }
/* every avatar after the first has its left 10px (8 overlap + 2 ring) under the one before: its text moves into the part that shows. At 24 and 32 two characters no longer fit, so a Chinese name shows its last character (at 24 that is so outside a group too) */
.sg-avatars-item + .sg-avatars-item .sg-avatar-text { transform: translateX(5px); }
.sg-avatar--more.is-long .sg-avatar-text { font-size: .8em; }
.sg-avatars--24 .sg-avatar-lead, .sg-avatars--32 .sg-avatar-lead { display: none; }
/* 24px is 12px type (the smallest text in the system), which holds one Chinese character: its last one — alone as well as in a group. English initials keep both letters alone; in a 24px group only the first fits the visible part */
.sg-avatar--24 .sg-avatar-lead, .sg-avatars--24 .sg-avatar-tail { display: none; }
/* 40px: two characters at 15px fill the 30px that show exactly; 13px leaves 2px on each side */
.sg-avatars--40 .sg-avatar-text { font-size: 13px; }

@media (prefers-reduced-motion: reduce) {
  .sg-avatar-img { transition-property: opacity; }
  button.sg-avatar { transition-property: background-color, color, opacity; }
  button.sg-avatar:active { transform: none; }
}
@media (pointer: coarse) {
  /* a 24 or 32px avatar used as a button gets a 44px target; the look does not change */
  button.sg-avatar--24::after, button.sg-avatar--32::after { content: ""; position: absolute; inset: calc((var(--av) - 44px) / 2); border-radius: 50%; }
}

/* ---------- BackTop: 44px glass IconButton at the bottom right; a 2px ring around it is the reading progress ---------- */
.sg-backtop { position: fixed; z-index: var(--z-sticky); box-sizing: border-box; width: var(--control-md); height: var(--control-md);
  right: calc(var(--space-4) + env(safe-area-inset-right, 0px));
  bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px) + var(--sg-bottom-offset, 0px)); }
.sg-backtop[data-state="open"] { animation: sg-backtop-in var(--duration-quick) var(--ease-liquid) both; }
.sg-backtop[data-state="closed"] { pointer-events: none; animation: sg-backtop-out calc(var(--duration-quick) * 2 / 3) var(--ease-exit) both; }
@keyframes sg-backtop-in { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }
@keyframes sg-backtop-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: scale(.96); } }
.sg-backtop-ring { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; transform: rotate(-90deg); }
.sg-backtop-ring circle { fill: none; stroke-width: 2; }
.sg-backtop-track { stroke: var(--line); }
.sg-backtop-bar { stroke: var(--ink); stroke-linecap: round; }

@media (prefers-reduced-motion: reduce) {
  @keyframes sg-backtop-in { from { opacity: 0; } to { opacity: 1; } }
  @keyframes sg-backtop-out { from { opacity: 1; } to { opacity: 0; } }
}
@media (pointer: coarse) {
  /* already 44px: nothing smaller than a finger */
}

/* ---------- Badge: status-bad pill with a mono count, or an 8px dot. The ring separates it from what it sits on. ---------- */
.sg-badge-wrap { position: relative; display: inline-flex; flex: none; vertical-align: middle; }
.sg-badge { --bg: var(--status-bad); --fg: var(--on-status-bad); box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; flex: none; vertical-align: middle;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-pill); background: var(--bg); color: var(--fg);
  font-family: var(--font-mono); font-size: 12px; line-height: 18px; font-weight: 500; letter-spacing: 0; white-space: nowrap; font-variant-numeric: tabular-nums; user-select: none; -webkit-user-select: none;
  pointer-events: none; }   /* a readout, never a target: clicks and hover go to whatever it sits on */
.sg-badge.is-ink { --bg: var(--ink); --fg: var(--ink-inverse); }
.sg-badge--dot { min-width: 0; width: 8px; height: 8px; padding: 0; }
.sg-badge-n { display: block; }
/* pinned: the badge's centre sits on the top-right corner, moved inward by --sg-badge-off (round targets want about 4px, squares 0) */
.sg-badge.is-pinned { position: absolute; z-index: 1; top: var(--sg-badge-off, 4px); right: var(--sg-badge-off, 4px); translate: 50% -50%; box-shadow: 0 0 0 2px var(--sg-badge-ring, var(--mist-000)); }
/* appears and goes away only when the count changes after first paint */
.sg-badge.is-anim[data-state="open"] { animation: sg-badge-in var(--duration-base) var(--ease-spring-bouncy) both; }
.sg-badge[data-state="closed"] { animation: sg-badge-out calc(var(--duration-base) * 2 / 3) var(--ease-exit) both; }
@keyframes sg-badge-in { from { opacity: 0; scale: .4; } }
@keyframes sg-badge-out { to { opacity: 0; scale: .6; } }
@keyframes sg-badge-fade-in { from { opacity: 0; } }
@keyframes sg-badge-fade-out { to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .sg-badge.is-anim[data-state="open"] { animation-name: sg-badge-fade-in; }
  .sg-badge[data-state="closed"] { animation-name: sg-badge-fade-out; }
  .sg-badge .sg-blur-in { animation: none; }
}
@media (pointer: coarse) {
  /* a badge is a readout, never a target (pointer-events: none above): nothing to enlarge */
  .sg-badge { pointer-events: none; }
}

/* ---------- data colours, shared by BarChart · Sparkline · DonutChart (this slice owns the block) ----------
   Fixed order magenta → indigo → ember → teal. The raw pulse-* tokens fail the dataviz checks next to each other
   (magenta ↔ indigo ΔE 6.0 in light, 4.7 in dark; indigo 2.0:1 on the dark surface), so the slots are nudged along their own hue
   toward their glow-* partner: light only moves magenta (80% pulse + 20% glow), dark lifts three slots. Validation: staging/L9/validate-palette.txt */
.sg-bars, .sg-spark, .sg-donut, .sg-lines {
  --sg-ch-ink: var(--ink); --sg-ch-ink-2: var(--ink-2); --sg-ch-line: var(--line);
  --sg-ch-c1: color-mix(in srgb, var(--pulse-magenta) 80%, var(--glow-magenta)); --sg-ch-c2: var(--pulse-indigo); --sg-ch-c3: var(--pulse-ember); --sg-ch-c4: var(--pulse-teal);
  --sg-ch-n1: color-mix(in srgb, var(--ink) 62%, transparent); --sg-ch-n2: color-mix(in srgb, var(--ink) 42%, transparent); --sg-ch-n3: color-mix(in srgb, var(--ink) 26%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) :is(.sg-bars, .sg-spark, .sg-donut, .sg-lines):not(.sg-ch--nebula) {
    --sg-ch-c1: color-mix(in srgb, var(--pulse-magenta) 40%, var(--glow-magenta)); --sg-ch-c2: color-mix(in srgb, var(--pulse-indigo) 65%, var(--glow-indigo));
    --sg-ch-c3: var(--pulse-ember); --sg-ch-c4: color-mix(in srgb, var(--pulse-teal) 70%, var(--glow-teal)); }
}
:root[data-theme="dark"] :is(.sg-bars, .sg-spark, .sg-donut, .sg-lines):not(.sg-ch--nebula) {
  --sg-ch-c1: color-mix(in srgb, var(--pulse-magenta) 40%, var(--glow-magenta)); --sg-ch-c2: color-mix(in srgb, var(--pulse-indigo) 65%, var(--glow-indigo));
  --sg-ch-c3: var(--pulse-ember); --sg-ch-c4: color-mix(in srgb, var(--pulse-teal) 70%, var(--glow-teal)); }
/* on a NebulaPanel the chart reads in light ink and the glow colours */
.sg-ch--nebula {
  --sg-ch-ink: var(--on-nebula); --sg-ch-ink-2: var(--on-nebula-2); --sg-ch-line: color-mix(in srgb, var(--on-nebula) 22%, transparent);
  --sg-ch-c1: var(--glow-magenta); --sg-ch-c2: var(--glow-indigo); --sg-ch-c3: var(--glow-ember); --sg-ch-c4: var(--glow-teal);
  --sg-ch-n1: color-mix(in srgb, var(--on-nebula) 60%, transparent); --sg-ch-n2: color-mix(in srgb, var(--on-nebula) 40%, transparent); --sg-ch-n3: color-mix(in srgb, var(--on-nebula) 25%, transparent);
}

/* ---------- BarChart ---------- */
.sg-bars { position: relative; display: block; width: 100%; box-sizing: border-box; color: var(--sg-ch-ink); border-radius: var(--radius-xs); font-family: var(--font-sans); }
.sg-bars.is-loading { opacity: .5; transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-bars-plot { position: relative; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.sg-bars-svg { display: block; overflow: visible; }
.sg-bars-svg text { font-family: var(--font-sans); font-size: 12px; font-weight: 400; font-variant-numeric: tabular-nums; fill: var(--sg-ch-ink-2); transition: fill var(--duration-base) var(--ease-liquid); }
.sg-bars-svg text.is-cur { fill: var(--sg-ch-ink); font-weight: 500; }
.sg-bars-grid { stroke: var(--sg-ch-line); stroke-width: 1; stroke-dasharray: 2 4; fill: none; }
.sg-bars-base { stroke: var(--sg-ch-line); stroke-width: 1; fill: none; }
.sg-bars-mark { fill: var(--c); transition: opacity var(--duration-base) var(--ease-liquid); }
/* single series: the current column is solid ink, the rest sit at 22%; several series: the hovered mark stays, the rest step back */
.sg-bars--one[data-dim] .sg-bars-mark { opacity: .22; }
.sg-bars[data-dim]:not(.sg-bars--one) .sg-bars-mark { opacity: .38; }
.sg-bars[data-dim] .sg-bars-mark.is-cur { opacity: 1; }
/* data change: the columns rise out of the baseline (clipped at the baseline), staggered; the first render never plays this */
@keyframes sg-bars-rise { from { transform: translateY(var(--h, 100%)); } }
@keyframes sg-bars-fade { from { opacity: 0; } }
.sg-bars-col.is-rise { animation: sg-bars-rise var(--duration-slow) var(--ease-liquid) backwards; animation-delay: var(--d, 0ms); }
/* readout above the current mark: glass pill, 12px figures; glides between marks on the SignalCurve spring */
.sg-bars-tip { position: absolute; left: 0; top: 0; width: 0; height: 0; z-index: 1; pointer-events: none; transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-bars-tip-in { position: absolute; left: 0; bottom: 0; display: flex; align-items: center; gap: 6px; height: 22px; padding: 0 10px; box-sizing: border-box; border-radius: var(--radius-pill); transform: translateX(-50%); white-space: nowrap;
  background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-glass); -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm));
  font-size: 12px; line-height: 1; color: var(--sg-ch-ink); font-variant-numeric: tabular-nums; }
.sg-bars-tip-in b { font-weight: 500; }
.sg-bars-tip-in i { width: 6px; height: 6px; border-radius: 50%; background: var(--c); flex: none; }
.sg-bars-tip-cat, .sg-bars-tip-name { color: var(--sg-ch-ink-2); }
.sg-ch--nebula .sg-bars-tip-in { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.4); box-shadow: none; }
/* legend: always present for two or more series */
.sg-bars-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 12px 0 0; padding: 0; list-style: none; font-size: 12px; line-height: 18px; color: var(--sg-ch-ink-2); }
.sg-bars-legend li { display: inline-flex; align-items: center; gap: 6px; transition: color var(--duration-instant); }
.sg-bars-legend li.is-cur { color: var(--sg-ch-ink); }
.sg-bars-legend i { width: 10px; height: 10px; border-radius: 3px; background: var(--c); flex: none; }
/* loading: columns drawn as skeleton */
.sg-bars-skel { display: flex; align-items: flex-end; justify-content: space-around; gap: 12px; height: calc(100% - 28px); padding: 32px 8px 0; box-sizing: border-box; }
.sg-bars-skel .sg-skel { flex: 0 1 24px; border-radius: var(--radius-pill) var(--radius-pill) 0 0; }

@media (prefers-reduced-motion: reduce) {
  .sg-bars-tip { transition-property: opacity !important; }
  .sg-bars-col.is-rise { animation-name: sg-bars-fade !important; animation-duration: var(--duration-base) !important; animation-delay: 0ms !important; }
}
@media (pointer: coarse) {
  /* the whole plot is the target: the finger picks the nearest column by its x position, not by landing on a 6px bar */
  .sg-bars-plot { min-height: 44px; }
}

/* ---------- Breadcrumb: 13 px ink-2 links, chevron-right 14 ink-3 between levels, the current page ink 500. Over four levels the middle folds into a "…" menu. ---------- */
.sg-crumbs { min-width: 0; font-size: 13px; line-height: 20px; color: var(--ink-2); }
.sg-crumbs-list { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; flex-wrap: nowrap; gap: var(--space-1); min-width: 0; }
.sg-crumbs-item { display: flex; align-items: center; gap: var(--space-1); flex: 0 1 auto; min-width: calc(2em + 18px); }   /* a level never squeezes below two characters and its chevron */
/* in a narrow container the current page gives way first, then the levels before it */
.sg-crumbs-item:last-child { flex-shrink: 8; min-width: 6em; }
.sg-crumbs-item.is-more { flex-shrink: 0; min-width: 0; }
.sg-crumb-sep { width: 14px; height: 14px; flex: none; color: var(--ink-3); }

.sg-crumb { position: relative; display: inline-flex; align-items: center; gap: var(--space-1); min-width: 0; max-width: 200px; flex: 0 1 auto;
  margin: -2px -4px; padding: 2px 4px; border: 0; border-radius: var(--radius-xs); background: none; color: var(--ink-2); font: inherit; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: color var(--duration-quick) var(--ease-liquid); }   /* the padding gives the focus ring room around the text; the negative margin keeps the layout as if it were not there */
.sg-crumb-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: 3px;
  transition: text-decoration-color var(--duration-quick) var(--ease-liquid); }
.sg-crumb-icon { width: 16px; height: 16px; flex: none; }
a.sg-crumb:hover, button.sg-crumb:hover { color: var(--ink); }
a.sg-crumb:hover .sg-crumb-text, button.sg-crumb:hover .sg-crumb-text { text-decoration-color: var(--line-strong); }
a.sg-crumb:active, button.sg-crumb:active { color: var(--ink); opacity: .7; }
span.sg-crumb { cursor: default; }
.sg-crumb-more { height: 24px; box-sizing: border-box; }   /* as tall as a text level (20 px line + 2 px either side); the 16 px dots icon sits in the middle */
.sg-crumb-more .sg-icon { width: 16px; height: 16px; }
.sg-crumb-more[aria-expanded="true"] { color: var(--ink); background: var(--state-hover); }
.sg-crumb.is-current { max-width: 280px; margin: 0; padding: 0; color: var(--ink); font-weight: 500; }   /* no focus ring to make room for, and no negative margin to push the bar's scroll width past its box */

@media (prefers-reduced-motion: reduce) {
  /* nothing moves here; the colour and the underline simply switch */
  .sg-crumb, .sg-crumb-text { transition-duration: var(--duration-instant); }
}
@media (pointer: coarse) {
  /* a 24 px link (20 px line + 2 px padding either side) becomes a 44 px target: 44 tall, and at least 44 wide, centred on the level. Two neighbours' reaches overlap by about 1 px at worst (the chevron between them is 14 px) */
  a.sg-crumb::after, button.sg-crumb::after { content: ""; position: absolute; top: -10px; bottom: -10px; left: 50%; translate: -50% 0; width: calc(100% + 8px); min-width: 44px; }
}

/* ---------- Calendar: month grid. Cells are 40 (sm 32, touch 44) circles; the selected day is ink, a range is two ink circles joined by a state-selected band ---------- */
.sg-cal { --sg-cal-cell: 40px; display: inline-grid; gap: var(--space-2); width: max-content; max-width: 100%; box-sizing: border-box; color: var(--ink);
  font-size: 15px; line-height: 22px; user-select: none; -webkit-user-select: none; }
.sg-cal--sm { --sg-cal-cell: 32px; font-size: 14px; line-height: 20px; }

.sg-cal-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.sg-cal-title { flex: 1; min-width: 0; text-align: center; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sg-cal-title > span { display: inline-block; }
/* at the first or last allowed month the arrow stays focusable (aria-disabled) so keyboard focus is not thrown out */
.sg-cal-nav[aria-disabled="true"] { opacity: var(--disabled); pointer-events: none; }

.sg-cal-grid { width: calc(var(--sg-cal-cell) * 7); table-layout: fixed; border-collapse: separate; border-spacing: 0 2px; }
.sg-cal-grid th { padding: 0; height: calc(var(--sg-cal-cell) - 8px); font-size: 12px; line-height: 16px; font-weight: 500; color: var(--ink-2); text-align: center; }
.sg-cal--sm .sg-cal-grid th { height: 24px; }
.sg-cal-cell { position: relative; padding: 0; height: var(--sg-cal-cell); text-align: center; }

/* range band: a full-width strip behind the days, a half strip on the first and last day of the range, rounded where a week row ends */
.sg-cal-cell::before { content: ""; display: none; position: absolute; top: 0; bottom: 0; left: 0; right: 0; background: var(--state-selected); pointer-events: none; }
.sg-cal-cell.is-in::before, .sg-cal-cell.is-from::before, .sg-cal-cell.is-to::before { display: block; }
.sg-cal-cell.is-from::before { left: 50%; }
.sg-cal-cell.is-to::before { right: 50%; }
.sg-cal-cell.is-in:first-child::before { border-radius: var(--radius-pill) 0 0 var(--radius-pill); }
.sg-cal-cell.is-in:last-child::before { border-radius: 0 var(--radius-pill) var(--radius-pill) 0; }
.sg-cal-cell.is-preview::before { background: var(--state-hover); }

.sg-cal-day { --sg-cal-ring: 0 0 0 0 transparent; position: relative; z-index: 1; display: grid; place-items: center; box-sizing: border-box; width: var(--sg-cal-cell); height: var(--sg-cal-cell);
  margin: 0 auto; padding: 0; border: 0; border-radius: var(--radius-pill); background: transparent; color: var(--ink); font: inherit; line-height: 1; font-variant-numeric: tabular-nums;
  cursor: pointer; outline: none; touch-action: manipulation; -webkit-tap-highlight-color: transparent; box-shadow: var(--sg-cal-ring);
  transition: background-color var(--duration-instant) var(--ease-liquid), color var(--duration-instant) var(--ease-liquid), transform var(--duration-quick) var(--ease-liquid), box-shadow var(--duration-quick) var(--ease-liquid); }
.sg-cal-day.is-outside { color: var(--ink-3); }
.sg-cal-day.is-today { --sg-cal-ring: inset 0 0 0 1px var(--ink-2); }
.sg-cal-day.is-hot { --sg-cal-ring: inset 0 0 0 1.5px var(--ink); }
.sg-cal-day:active:not([aria-disabled="true"]) { background: var(--state-pressed); transform: scale(.92); }
.sg-cal-day[aria-disabled="true"] { opacity: var(--disabled); cursor: not-allowed; }
/* In the dark theme ink × --disabled lands on the same grey as the out-of-month ink-3, so a blocked day in this month looked like an out-of-month day you can pick.
   A hairline strike-through says "not available" without relying on that grey. Skipped when the whole calendar is disabled (nothing to tell apart). */
.sg-cal:not(.sg-cal--off) .sg-cal-day[aria-disabled="true"]:not(.is-outside) { text-decoration: line-through; text-decoration-thickness: 1px; }
.sg-cal-day.is-selected { --sg-cal-ring: 0 0 0 0 transparent; background: var(--ink); color: var(--ink-inverse); }
.sg-cal-day.is-selected:active:not([aria-disabled="true"]) { background: var(--ink); }
.sg-cal-day:focus-visible { box-shadow: var(--sg-cal-ring), 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); z-index: 2; }
@media (hover: hover) {
  .sg-cal-day:hover:not([aria-disabled="true"]):not(.is-selected) { background: var(--state-hover); }
}

/* a new month slides in from the side it came from; nothing plays on the first render */
.sg-cal-body[data-dir="next"] { animation: sg-cal-next var(--duration-base) var(--ease-liquid) both; }
.sg-cal-body[data-dir="prev"] { animation: sg-cal-prev var(--duration-base) var(--ease-liquid) both; }
@keyframes sg-cal-next { from { opacity: 0; transform: translateX(12px); } }
@keyframes sg-cal-prev { from { opacity: 0; transform: translateX(-12px); } }
@keyframes sg-cal-fade { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .sg-cal-day { transition-property: background-color, color, box-shadow; }
  .sg-cal-day:active:not([aria-disabled="true"]) { transform: none; }
  .sg-cal-body[data-dir] { animation-name: sg-cal-fade; animation-duration: var(--duration-quick); }
}
@media (pointer: coarse) {
  /* fingers: 44px days (the 32px arrows get their 44px hit area from IconButton) */
  .sg-cal, .sg-cal--sm { --sg-cal-cell: 44px; }
  .sg-cal--sm .sg-cal-grid th { height: 32px; }
}

/* ---------- Carousel: native horizontal scroll + scroll-snap; arrows, indicators and the autoplay switch sit on top ---------- */
.sg-carousel { position: relative; min-width: 0; }
.sg-carousel-stage { position: relative; min-width: 0; }
.sg-carousel-viewport { position: relative; container-type: inline-size; overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  scrollbar-width: none; border-radius: inherit; outline: none;
  /* room for the shadows of slides that have one (a card): the band grows by --sg-car-bleed above and below and the margin takes it back, so the layout does not change */
  padding-block: var(--sg-car-bleed, 0px); margin-block: calc(var(--sg-car-bleed, 0px) * -1); }
.sg-carousel-viewport::-webkit-scrollbar { display: none; }
/* the keyboard can scroll the band: the ring is drawn inside so the viewport's own clipping does not cut it */
.sg-carousel-viewport:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-halo), inset 0 0 0 4px var(--focus-ring); }
/* a slide is (the width of the band - gaps - the peek) / slides per view; cqw = the band's width, so the track can be as wide as all its slides and the end padding counts */
.sg-carousel-track { display: flex; gap: var(--sg-car-gap, 12px); width: max-content; padding-inline-end: var(--sg-car-pk, 0px); }
.sg-carousel-slide { flex: 0 0 calc((100cqw - (var(--sg-car-per, 1) - 1) * var(--sg-car-gap, 12px) - var(--sg-car-pk, 0px)) / var(--sg-car-per, 1)); min-width: 0; scroll-snap-align: start; scroll-snap-stop: always; }

/* arrows: IconButton sm glass, centred on the band, 12 in from the edge. They show on hover and on keyboard focus (always in the tab order); on a touch screen the swipe does it */
.sg-carousel-arrows { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.sg-carousel .sg-carousel-arrow { position: absolute; top: 50%; margin-top: calc(var(--control-sm) / -2); pointer-events: auto; opacity: 0; background: var(--glass-overlay);
  transition: opacity var(--duration-quick) var(--ease-liquid), background-color var(--duration-instant), transform var(--duration-quick) var(--ease-liquid); }
.sg-carousel-arrow--prev { left: var(--space-3); }
.sg-carousel-arrow--next { right: var(--space-3); }
.sg-carousel .sg-carousel-arrow:not([aria-disabled="true"]):hover { background: var(--glass-overlay); box-shadow: var(--shadow-lift); }
.sg-carousel:hover .sg-carousel-arrow, .sg-carousel:focus-within .sg-carousel-arrow, .sg-carousel .sg-carousel-arrows.is-always .sg-carousel-arrow { opacity: 1; }
/* at the end of the band (no loop) the arrow is dimmed like any disabled button, but only while the arrows are showing. It is aria-disabled, not disabled, so the keyboard focus can stay on it:
   no hover lift, no icon nudge, no press shrink */
.sg-carousel:hover .sg-carousel-arrow[aria-disabled="true"], .sg-carousel:focus-within .sg-carousel-arrow[aria-disabled="true"], .sg-carousel .sg-carousel-arrows.is-always .sg-carousel-arrow[aria-disabled="true"] { opacity: var(--disabled); }
.sg-carousel .sg-carousel-arrow[aria-disabled="true"] { cursor: not-allowed; }
.sg-carousel .sg-carousel-arrow[aria-disabled="true"]:hover { background: var(--glass-overlay); box-shadow: none; }
.sg-carousel .sg-carousel-arrow[aria-disabled="true"]:hover .sg-icon { transform: none; }
.sg-carousel .sg-carousel-arrow[aria-disabled="true"]:active { transform: none; }
@media (hover: none) { .sg-carousel:not(:focus-within) .sg-carousel-arrows:not(.is-always) .sg-carousel-arrow { pointer-events: none; } }

/* autoplay switch: xs glass, top right, first in the tab order */
.sg-carousel .sg-carousel-play { position: absolute; top: var(--space-2); right: var(--space-2); z-index: 3; background: var(--glass-overlay); }
.sg-carousel .sg-carousel-play:not([disabled]):hover { background: var(--glass-overlay); }

/* indicators */
.sg-carousel-ind { display: flex; align-items: center; justify-content: center; min-width: 0; }
.sg-carousel-ind:not(.is-overlay) { margin-top: var(--space-3); }
/* over a picture: a glass-overlay capsule, never marks drawn straight on the image */
.sg-carousel-ind.is-overlay { position: absolute; z-index: 2; bottom: var(--space-3); left: 50%; transform: translateX(-50%); max-width: calc(100% - var(--space-6)); box-sizing: border-box; padding: 0 var(--space-2);
  background: var(--glass-overlay); border: 1px solid var(--line); border-radius: var(--radius-pill);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-carousel-ind.sg-carousel-ind--count { position: absolute; z-index: 2; right: var(--space-3); bottom: var(--space-3); left: auto; transform: none; padding: 0 var(--space-3); }
.sg-carousel-countnum { font-size: 12px; line-height: 24px; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }

.sg-carousel-stop { position: relative; display: grid; place-items: center; flex: none; margin: 0; padding: 0; border: 0; background: none; cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }
/* dots: 6px ink-3; the current one is an 18 x 6 ink capsule whose width springs */
.sg-carousel-stop--dots { width: 18px; height: 24px; }
.sg-carousel-dot { display: block; width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--ink-3);
  transition: width var(--duration-spring) var(--ease-spring-soft), background-color var(--duration-quick) var(--ease-liquid); }
.sg-carousel-stop--dots:hover .sg-carousel-dot { background: var(--ink-2); }
.sg-carousel-stop--dots.is-current .sg-carousel-dot { width: 18px; background: var(--ink); }
.sg-carousel-stop:focus-visible .sg-carousel-dot, .sg-carousel-stop:focus-visible .sg-carousel-bar { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
/* bars: one 2px segment per slide; with autoplay the current one fills with ink over the slide's time, the ones before it are full */
.sg-carousel-ind--bars { gap: 4px; align-self: stretch; }
.sg-carousel-ind.sg-carousel-ind--bars.is-overlay { align-self: auto; width: calc(100% - var(--space-6)); }
.sg-carousel-stop--bars { flex: 1 1 0; min-width: 12px; height: 24px; }
.sg-carousel-bar { position: relative; display: block; width: 100%; height: 2px; border-radius: var(--radius-pill); background: var(--line-strong); overflow: hidden; }
.sg-carousel-fill { position: absolute; inset: 0; background: var(--ink); transform-origin: left center; transform: scaleX(0); }
.sg-carousel-stop.is-current .sg-carousel-fill, .sg-carousel-stop.is-past .sg-carousel-fill { transform: scaleX(1); }
.sg-carousel-fill.is-run { animation: sg-carousel-fill 5000ms linear both; }
.sg-carousel-ind.is-hold .sg-carousel-fill.is-run { animation-play-state: paused; }
@keyframes sg-carousel-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

@media (forced-colors: active) {
  .sg-carousel-dot, .sg-carousel-fill { forced-color-adjust: none; background: CanvasText; }
}
@media (prefers-reduced-motion: reduce) {
  /* no autoplay by default; the current dot changes width and the bar fills at once instead of easing, and the band scrolls with a jump (the script) */
  .sg-carousel-dot { transition: background-color var(--duration-quick) var(--ease-liquid); }
  .sg-carousel-fill.is-run { animation: none; transform: scaleX(1); }
  .sg-carousel-arrow { transition-property: opacity, background-color; }
}
@media (pointer: coarse) {
  /* arrows are hidden on touch (swipe); the xs switch reaches 44 through core's ::after. Indicator buttons: under the picture they are 44 high themselves (dots 24 wide);
     in the glass capsule on the picture they keep their 24 and the 44 high hit area is a ::after, so the capsule looks the same as with a mouse */
  .sg-carousel-ind:not(.is-overlay) .sg-carousel-stop--dots { width: 24px; height: 44px; }
  .sg-carousel-ind:not(.is-overlay) .sg-carousel-stop--bars { height: 44px; }
  .sg-carousel-ind.is-overlay .sg-carousel-stop::after { content: ""; position: absolute; inset: -10px 0; }
  .sg-carousel .sg-carousel-play { position: absolute; }
}

/* ---------- Cascader: recipe A shell whose face is the trigger button; the panel is a floating list per level (180 x 280); on a touch screen the same lists sit in an ActionSheet under a tab per level ---------- */
.sg-cascader.sg-field-box { padding: 0; min-width: 0; cursor: pointer; }
.sg-cascader.is-disabled { cursor: not-allowed; }
.sg-cascader.is-open { border-color: var(--ink); }
.sg-cascader-trigger { flex: 1; min-width: 0; height: 100%; display: flex; align-items: center; gap: var(--space-2); box-sizing: border-box; margin: 0; padding: 0 0 0 14px; border: 0; border-radius: inherit;
  background: none; color: inherit; font: inherit; font-size: 15px; text-align: start; cursor: inherit; outline: none; }
.sg-cascader.sg-field-box--sm .sg-cascader-trigger { padding-left: 12px; font-size: 14px; }
.sg-cascader-text { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-cascader-text.is-placeholder { color: var(--ink-2); }
.sg-cascader-sep { color: var(--ink-2); white-space: pre; }
/* the arrow sits after the clear button, outside the trigger (Select's order: value · clear · arrow); a press on it opens the panel too */
.sg-cascader-caret { flex: none; align-self: stretch; display: grid; place-items: center; padding-right: 14px; color: var(--ink-2); cursor: inherit; }
.sg-cascader.sg-field-box--sm .sg-cascader-caret { padding-right: 12px; }
.sg-cascader-caret .sg-icon { width: 16px; height: 16px; transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-cascader.is-open .sg-cascader-caret .sg-icon { transform: rotate(180deg); }
.sg-cascader-clear { flex: none; }

/* the panel: radius-sm, no padding of its own (the columns run edge to edge); at most 4 columns wide, then it scrolls sideways */
.sg-overlay.sg-cascader-panel { padding: 0; border-radius: var(--radius-sm); width: max-content; max-width: min(726px, var(--sg-avail-w, 100vw)); overflow: hidden; display: flex; flex-direction: column; max-height: none; }
.sg-cascader-cols { display: flex; min-width: 0; overflow-x: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--scrollbar) transparent; }
.sg-cascader-col { flex: none; box-sizing: border-box; width: 180px; height: 280px; border-right: 1px solid var(--line); }
.sg-cascader-col:last-child { border-right: 0; }
.sg-cascader-lb { height: 100%; outline: none; }
.sg-cascader-scroll { height: 100%; border-radius: 0; }
.sg-cascader-menu { padding: 4px; }
.sg-cascader-opt { gap: var(--space-2); }
.sg-cascader-opt .sg-menu-title { white-space: nowrap; }
.sg-cascader-more { flex: none; width: 14px; height: 14px; color: var(--ink-2); }
.sg-cascader-check { flex: none; width: 16px; height: 16px; color: var(--ink); }
.sg-cascader-busy { flex: none; color: var(--ink-2); }
/* the levels on the current path: state-selected and 500 */
.sg-cascader-opt[aria-selected="true"] { background: var(--state-selected); font-weight: 500; }
/* the keyboard's row is only drawn while the list has focus (the pointer's hover is :hover, below) */
.sg-menu-item.sg-cascader-opt[data-active] { background: transparent; }
.sg-menu-item.sg-cascader-opt[aria-selected="true"][data-active] { background: var(--state-selected); }
/* … and drawn as the same state-hover tint every other option list uses (recipe E); on a path level it lies over state-selected */
.sg-cascader-lb:focus-visible .sg-menu-item.sg-cascader-opt[data-active] { background: var(--state-hover); }
.sg-cascader-lb:focus-visible .sg-menu-item.sg-cascader-opt[aria-selected="true"][data-active] { background: linear-gradient(var(--state-hover), var(--state-hover)), var(--state-selected); }
.sg-cascader-opt.is-disabled { opacity: var(--disabled); cursor: not-allowed; }

/* failed / waiting level */
.sg-cascader-fail, .sg-cascader-wait { height: 100%; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-2); padding: var(--space-4); color: var(--ink-2); font-size: 14px; text-align: center; }
.sg-cascader-fail-t { color: var(--ink-2); }
.sg-cascader-wait { flex-direction: row; gap: var(--space-3); }

/* search */
.sg-cascader-search { flex: none; display: flex; align-items: center; gap: var(--space-2); min-height: 48px; box-sizing: border-box; padding: 0 var(--space-3) 0 14px; border-bottom: 1px solid var(--line); }
.sg-cascader-search-in { flex: 1; min-width: 0; height: 36px; padding: 0; border: 0; outline: none; background: none; font: inherit; font-size: 15px; color: var(--ink); }
.sg-cascader-search-in::placeholder { color: var(--ink-2); opacity: 1; }
.sg-cascader-search:focus-within { box-shadow: inset 0 -2px 0 var(--ink); }
.sg-cascader-results { padding: 4px; min-width: 320px; max-height: 280px; overflow-y: auto; overscroll-behavior: contain; box-sizing: border-box; }
.sg-cascader-res .sg-menu-title { color: var(--ink-2); }
.sg-cascader-hit { color: var(--ink); font-weight: 500; }
.sg-cascader-res[data-active] { background: var(--state-hover); }
.sg-cascader-none { min-width: 320px; padding: var(--space-6) var(--space-4); }

/* touch: inside the sheet */
.sg-cascader-sheet { margin: 0 calc(var(--space-4) * -1); }
.sg-cascader-sheet .sg-cascader-search { margin: 0 var(--space-4); }
.sg-cascader-tabs { padding: 0 var(--space-2); }
.sg-cascader-sheetbody { height: min(288px, 46vh); }
.sg-cascader-lb.is-touch .sg-cascader-menu { padding: 4px var(--space-2); }
.sg-cascader-lb.is-touch .sg-cascader-opt { min-height: 48px; font-size: 16px; }
.sg-cascader-sheet .sg-cascader-results { max-height: min(336px, 52vh); min-width: 0; }
.sg-cascader-sheet .sg-cascader-none { min-width: 0; }

@media (prefers-reduced-motion: reduce) {
  .sg-cascader-caret .sg-icon { transition: none; }
  .sg-cascader.is-open .sg-cascader-caret .sg-icon { transform: none; }
}
@media (pointer: coarse) {
  /* an xs clear button reaches 44 through IconButton's own touch rule; rows are 44 (menu rows) in the floating panel, 48 in the sheet */
  .sg-cascader-clear { position: relative; z-index: 1; }
  .sg-cascader .sg-cascader-caret { padding-left: 6px; }
}
@media (max-width: 479px) {
  .sg-cascader-col { width: min(180px, 46vw); }
}

/* ---------- Checkbox: 20px mark (recipe B), native input on top for forms, keyboard and the label click ---------- */
.sg-check-wrap { display: grid; gap: 4px; min-width: 0; align-content: start; justify-items: start; }
.sg-check { position: relative; display: inline-grid; grid-template-columns: 20px minmax(0, 1fr); column-gap: var(--space-3); align-items: start; max-width: 100%; min-height: 24px; cursor: pointer;
  color: var(--ink); font-size: 15px; line-height: 22px; -webkit-tap-highlight-color: transparent; }
.sg-check.is-bare { grid-template-columns: 20px; min-height: 20px; }
.sg-check--sm { column-gap: var(--space-2); font-size: 14px; line-height: 20px; min-height: 20px; }
/* the real input covers the mark: it is what the screen reader, the form and the keyboard talk to */
.sg-check-input { position: absolute; z-index: 1; left: 0; top: 1px; width: 20px; height: 20px; margin: 0; opacity: 0; cursor: inherit; }
.sg-check--sm .sg-check-input { top: 0; }
.sg-check-box { position: relative; grid-column: 1; grid-row: 1; margin-top: 1px; width: 20px; height: 20px; box-sizing: border-box; display: grid; place-items: center; flex: none;
  border-radius: calc(var(--radius-xs) * .75); border: 1.5px solid var(--line-strong); background: var(--glass-strong); color: var(--ink-inverse);
  transition: background-color var(--duration-quick) var(--ease-liquid), border-color var(--duration-quick) var(--ease-liquid), box-shadow var(--duration-quick) var(--ease-liquid), transform var(--duration-quick) var(--ease-liquid); }
.sg-check--sm .sg-check-box { margin-top: 0; }
.sg-check-box[data-state="checked"], .sg-check-box[data-state="mixed"] { background: var(--ink); border-color: var(--ink); }
.sg-check-svg { width: 20px; height: 20px; margin: -1.5px; overflow: visible; }
.sg-check-tick, .sg-check-dash { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* leaving: 2/3 of the time, ease-exit; entering (below) draws the tick in */
.sg-check-tick { stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0;
  transition: stroke-dashoffset calc(var(--duration-quick) * 2 / 3) var(--ease-exit), opacity calc(var(--duration-quick) * 2 / 3) var(--ease-exit); }
.sg-check-box[data-state="checked"] .sg-check-tick { stroke-dashoffset: 0; opacity: 1; transition: stroke-dashoffset var(--duration-quick) var(--ease-liquid), opacity var(--duration-instant) linear; }
.sg-check-dash { transform-origin: 10px 10px; transform: scaleX(0); opacity: 0;
  transition: transform calc(var(--duration-quick) * 2 / 3) var(--ease-exit), opacity calc(var(--duration-quick) * 2 / 3) var(--ease-exit); }
.sg-check-box[data-state="mixed"] .sg-check-dash { transform: none; opacity: 1; transition: transform var(--duration-quick) var(--ease-liquid), opacity var(--duration-instant) linear; }

.sg-check-text { grid-column: 2; display: grid; min-width: 0; }
.sg-check-title { overflow-wrap: anywhere; }
.sg-check-hint { font-size: 13px; line-height: 18px; color: var(--ink-2); }
.sg-check--sm .sg-check-hint { font-size: 12px; line-height: 16px; }

/* states: hover / press are an overlay ring around the mark (state-hover / state-pressed), never a colour swap; hover only where there is a pointer that hovers */
@media (hover: hover) {
  .sg-check:not(.is-disabled):hover .sg-check-box { box-shadow: 0 0 0 6px var(--state-hover); }
  .sg-check:not(.is-disabled):hover .sg-check-box[data-state="unchecked"] { border-color: var(--ink-2); }
}
.sg-check:not(.is-disabled):active .sg-check-box { transform: scale(.92); box-shadow: 0 0 0 6px var(--state-pressed); }
.sg-check-input:focus-visible + .sg-check-box, .sg-check:not(.is-disabled):hover .sg-check-input:focus-visible + .sg-check-box { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-check.is-invalid .sg-check-box[data-state="unchecked"] { border-color: var(--status-bad); }
.sg-check.is-invalid .sg-check-box[data-state="checked"], .sg-check.is-invalid .sg-check-box[data-state="mixed"] { box-shadow: 0 0 0 2px var(--status-bad); }
.sg-check.is-invalid .sg-check-input:focus-visible + .sg-check-box, .sg-check.is-invalid:not(.is-disabled):hover .sg-check-input:focus-visible + .sg-check-box { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--status-bad); }
.sg-check.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-check-err { margin: 0; }
.sg-check-err.is-indented { margin-left: 32px; }

/* group: a vertical list, or a row; the select-all row sits above a hairline */
.sg-check-group { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); min-width: 0; }
.sg-check-group--row { flex-direction: row; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2) var(--space-6); }
.sg-check-sep { align-self: stretch; height: 1px; background: var(--line); margin: 0; }
.sg-check-group--row .sg-check-sep { align-self: center; width: 1px; height: 20px; }

@media (prefers-reduced-motion: reduce) {
  .sg-check-box { transition-property: background-color, border-color, box-shadow; }
  .sg-check:not(.is-disabled):active .sg-check-box { transform: none; }
  .sg-check-box .sg-check-tick, .sg-check-box[data-state] .sg-check-tick { stroke-dashoffset: 0; transition-property: opacity; }
  .sg-check-box .sg-check-dash, .sg-check-box[data-state] .sg-check-dash { transform: none; transition-property: opacity; }
}
@media (pointer: coarse) {
  /* the whole row is the target: at least 44px tall, the mark stays 20px and centred on the first line */
  .sg-check { min-height: 44px; }
  .sg-check.is-bare { min-height: 20px; }
  .sg-check-input { top: 12px; }
  .sg-check-box { margin-top: 12px; }
  .sg-check--sm .sg-check-input { top: 12px; }
  .sg-check--sm .sg-check-box { margin-top: 12px; }
  .sg-check-text { padding-block: 11px; }
  .sg-check--sm .sg-check-text { padding-block: 12px; }
  .sg-check.is-bare .sg-check-input, .sg-check.is-bare .sg-check-box { top: 0; margin-top: 0; }
  .sg-check.is-bare::after { content: ""; position: absolute; inset: -12px; }
  .sg-check-group { gap: 0; }
  .sg-check-group--row { gap: 0 var(--space-6); }
}

/* ---------- CodeBlock: a sunken mist surface (mist-100, 1px line, radius-sm). Bar 40 high with the file name or language (or Tabs) and a CopyButton; Geist Mono 13 / 20 below ---------- */
.sg-codeblock { position: relative; min-width: 0; box-sizing: border-box; overflow: hidden; background: var(--mist-100); border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--ink); font-family: var(--font-mono); text-align: left; }
.sg-codeblock-bar { display: flex; align-items: center; min-width: 0; height: 40px; box-sizing: border-box; padding: 0 48px 0 var(--space-4); border-bottom: 1px solid var(--line); }
.sg-codeblock-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-2); }
.sg-codeblock .sg-codeblock-copy { position: absolute; top: var(--space-2); right: var(--space-2); z-index: 3; }

/* several files: the L10 Tabs (line, sm) take the bar; the copy button floats over its right end */
.sg-codeblock .sg-tabbed-bar { padding: 3px 48px 0 var(--space-2); }
.sg-codeblock .sg-tabbed:not(.sg-tabbed--v) > .sg-tabbed-panel { padding-top: 0; }
.sg-codeblock .sg-tabbed-panel.is-anim { animation: none; }

.sg-codeblock-body { position: relative; min-width: 0; }
.sg-codeblock .sg-scrollarea { border-radius: 0; }
/* the ring of the focusable scroll region is drawn inside: the block clips anything outside it */
.sg-codeblock .sg-scrollarea.is-focus { box-shadow: inset 0 0 0 2px var(--focus-halo), inset 0 0 0 4px var(--focus-ring); }
.sg-codeblock-scroll.is-wrap { min-width: 0; }

/* lines: the list is as wide as its longest line (or the box), so a highlighted or changed line fills the full width when scrolled */
.sg-codeblock-lines { display: block; width: max-content; min-width: 100%; box-sizing: border-box; padding: var(--space-3) 0; font-size: 13px; line-height: 20px; font-variant-ligatures: none; tab-size: 2; }
.sg-codeblock.is-wrap .sg-codeblock-lines { width: auto; min-width: 0; }
.sg-codeblock-line { display: flex; align-items: flex-start; min-height: 20px; padding: 0 var(--space-4); box-sizing: border-box; }
.sg-codeblock-ln { flex: none; min-width: calc(var(--sg-cb-digits, 1) * 1ch); margin-right: var(--space-4); text-align: right; color: var(--ink-3); font-variant-numeric: tabular-nums; user-select: none; -webkit-user-select: none; }
.sg-codeblock-sign { flex: none; width: 1ch; margin-right: var(--space-2); text-align: center; user-select: none; -webkit-user-select: none; }
.sg-codeblock-text { flex: none; white-space: pre; text-decoration: none; }
.sg-codeblock.is-wrap .sg-codeblock-text { flex: 1 1 0; min-width: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.sg-codeblock-prompt { color: var(--ink-3); user-select: none; -webkit-user-select: none; }
.sg-codeblock-cm { color: var(--ink-2); font-style: normal; }
.sg-codeblock-kw { font-weight: 600; }

/* highlighted lines: state-selected across the full width plus a 2px edge, so it is not colour alone */
.sg-codeblock-line.is-hl { background-image: linear-gradient(var(--state-selected), var(--state-selected)); box-shadow: inset 2px 0 0 color-mix(in srgb, var(--ink) 40%, transparent); }
/* diff: a 10% green / red wash, the sign in the margin (+ and −) and ins / del for assistive tech */
.sg-codeblock-line.is-add { background-color: color-mix(in srgb, var(--status-good) 10%, transparent); }
.sg-codeblock-line.is-del { background-color: color-mix(in srgb, var(--status-bad) 10%, transparent); }
.sg-codeblock-line.is-add .sg-codeblock-sign { color: var(--status-good); }
.sg-codeblock-line.is-del .sg-codeblock-sign { color: var(--status-bad); }
.sg-codeblock-line.is-hunk .sg-codeblock-text { color: var(--ink-2); }

/* folding (maxLines): the first lines stay, the rest sit in a grid row that goes 0fr → 1fr; a fade covers the last visible lines while it is shut */
.sg-codeblock-more { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--duration-smooth) var(--ease-spring-soft); }
.sg-codeblock-more.is-open { grid-template-rows: 1fr; }
.sg-codeblock-more-in { min-height: 0; overflow: hidden; }
.sg-codeblock-body.is-foldable::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 56px; pointer-events: none; opacity: 0; background: linear-gradient(to bottom, transparent, var(--mist-100));
  transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-codeblock-body.is-foldable.is-collapsed::after { opacity: 1; }
.sg-codeblock-foot { display: flex; justify-content: center; padding: var(--space-1) var(--space-2) var(--space-2); }

@media (forced-colors: active) {
  .sg-codeblock-line.is-add .sg-codeblock-sign, .sg-codeblock-line.is-del .sg-codeblock-sign { color: CanvasText; }
}
@media (prefers-reduced-motion: reduce) {
  /* the folded part opens at once; the fade at the foot still goes by opacity */
  .sg-codeblock-more { transition: none; }
}
@media (pointer: coarse) {
  /* the copy button is IconButton xs and keeps the system's 44px hit area; the fold button is Button sm (also 44 under a finger). Nothing else here is a target */
  .sg-codeblock-line { padding-left: var(--space-3); padding-right: var(--space-3); }
}

/* ---------- ColorPicker: a recipe A field (chip · hex), or just a chip button; the panel is a Popover (recipe D) with an area, a hue bar, an alpha bar, a value box and swatches.
   The area, the bars and the swatches draw the colour being chosen: their gradients are the picked colour itself, not interface colours (written as hsl() so no hex sits in this file). ---------- */
.sg-colorpick.sg-field-box { min-width: 0; gap: var(--space-2); padding: 0 14px 0 12px; }
.sg-colorpick.is-open { border-color: var(--ink); }
.sg-colorpick-text { font-family: var(--font-mono); letter-spacing: .02em; }
.sg-colorpick-clear { flex: none; margin-right: -4px; }
.sg-colorpick.sg-field-box--sm { padding: 0 12px 0 8px; }

/* the chip: a 20px disc, a 1px inner line so white and pale colours still read on glass, a checkerboard (4px cells) under a colour that is not opaque; empty = an outlined disc with a slash */
.sg-colorpick-chip { display: block; flex: none; box-sizing: border-box; width: 20px; height: 20px; border-radius: 50%;
  background: linear-gradient(var(--sg-cp-solid, transparent), var(--sg-cp-solid, transparent)), conic-gradient(var(--mist-200) 25%, var(--mist-000) 0 50%, var(--mist-200) 0 75%, var(--mist-000) 0) 0 0 / 8px 8px;
  box-shadow: inset 0 0 0 1px var(--line-strong); }
.sg-colorpick-chip.is-empty { background: linear-gradient(to top right, transparent calc(50% - .75px), var(--line-strong) calc(50% - .75px), var(--line-strong) calc(50% + .75px), transparent calc(50% + .75px)); box-shadow: inset 0 0 0 1px var(--line-strong); }
.sg-colorpick-chip-btn { flex: none; display: grid; place-items: center; width: 24px; height: 24px; margin: 0; padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer; outline: none; }
.sg-colorpick-chip-btn:disabled { cursor: not-allowed; }
.sg-colorpick-chip-btn:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-colorpick-msg.is-solo { margin: 6px 0 0; }
.sg-colorpick-msg.sg-field-error { display: flex; align-items: flex-start; gap: 6px; }

/* trigger="swatch": only the disc, 32px (sm 24) */
.sg-colorpick-swatchbtn { position: relative; display: block; box-sizing: border-box; width: 32px; height: 32px; margin: 0; padding: 0; border: 0; border-radius: 50%; background: none; cursor: pointer; outline: none; }
.sg-colorpick-swatchbtn.is-sm { width: 24px; height: 24px; }
.sg-colorpick-swatchbtn .sg-colorpick-chip { width: 100%; height: 100%; transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-colorpick-swatchbtn:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-colorpick-swatchbtn:disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-colorpick-swatchbtn[aria-expanded="true"] { box-shadow: 0 0 0 2px var(--ink); }

/* the panel: 288 wide in all, 256 of it content, 16 padding; rows 12 apart */
.sg-popover.sg-colorpick-pop { min-width: 0; }
.sg-colorpick-panel { display: grid; gap: var(--space-3); width: 100%; }
.sg-colorpick-inline { box-sizing: border-box; width: 288px; max-width: 100%; padding: var(--space-4); background: var(--glass); border: 1px solid var(--line); border-radius: var(--radius-md); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md)); }

/* the area: the hue as a flat colour, white from the left, black from the bottom */
.sg-colorpick-area { position: relative; height: 160px; border-radius: var(--radius-sm); cursor: crosshair; touch-action: none; outline: none; user-select: none; -webkit-user-select: none;
  background-image: linear-gradient(to top, hsl(0 0% 0%), hsl(0 0% 0% / 0)), linear-gradient(to right, hsl(0 0% 100%), hsl(0 0% 100% / 0)); box-shadow: inset 0 0 0 1px var(--line); }
.sg-colorpick-area:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-colorpick-knob { position: absolute; width: 16px; height: 16px; box-sizing: border-box; border-radius: 50%; border: 2px solid hsl(0 0% 100%); transform: translate(-50%, -50%); pointer-events: none;
  box-shadow: var(--shadow-lift), 0 0 0 1px hsl(0 0% 0% / .2); transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-colorpick-area.is-dragging .sg-colorpick-knob { transform: translate(-50%, -50%) scale(1.2); }

/* the bars: 12 high, a pill; the thumb is Slider's (.sg-slider-thumb: it stretches while held and springs back, like Slider and Switch) */
.sg-colorpick-bar { --sg-thumb: 18px; position: relative; height: 12px; border-radius: var(--radius-pill); cursor: pointer; touch-action: none; user-select: none; -webkit-user-select: none; box-shadow: inset 0 0 0 1px var(--line); }
.sg-colorpick-rail { position: absolute; top: 0; bottom: 0; left: calc(var(--sg-thumb) / 2); right: calc(var(--sg-thumb) / 2); }
.sg-colorpick-hue { background: linear-gradient(to right, hsl(0 100% 50%), hsl(60 100% 50%), hsl(120 100% 50%), hsl(180 100% 50%), hsl(240 100% 50%), hsl(300 100% 50%), hsl(360 100% 50%)); }
.sg-colorpick-alpha { background: linear-gradient(to right, color-mix(in srgb, var(--sg-cp-solid) 0%, transparent), var(--sg-cp-solid)), conic-gradient(var(--mist-200) 25%, var(--mist-000) 0 50%, var(--mist-200) 0 75%, var(--mist-000) 0) 0 0 / 8px 8px; }

/* the value row: eyedropper, HEX / RGB / HSL, then the box (mono) */
.sg-colorpick-fmt { display: flex; align-items: center; gap: var(--space-2); }
.sg-colorpick-fmt .sg-seg { flex: 1; min-width: 0; }
.sg-colorpick-eye { flex: none; }
.sg-colorpick-input .sg-field-input, .sg-colorpick-input .sg-field-prefix { font-family: var(--font-mono); letter-spacing: .02em; }

/* swatches: 24px discs in 32px cells (8 to a row, 8 apart); the chosen one gets a 2px ink ring 2px off */
.sg-colorpick-cap { margin: 0 0 var(--space-2); font-size: 12px; line-height: 16px; color: var(--ink-2); }
.sg-colorpick-swatches { display: grid; grid-template-columns: repeat(8, 1fr); justify-items: center; row-gap: var(--space-2); padding: 4px 0; margin: -4px 0; }
.sg-colorpick-swatch { position: relative; width: 24px; height: 24px; box-sizing: border-box; margin: 0; padding: 0; border: 1px solid var(--line-strong); border-radius: 50%; cursor: pointer; outline: none;
  transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-colorpick-swatch.is-on { outline: 2px solid var(--ink); outline-offset: 2px; }
.sg-colorpick-swatch:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-colorpick-swatch.is-on:focus-visible { outline-offset: 5px; }
.sg-colorpick-swatch:disabled { opacity: var(--disabled); cursor: not-allowed; }
@media (hover: hover) {
  .sg-colorpick-swatch:hover:not(:disabled) { transform: scale(1.08); }
}
.sg-colorpick-panel.is-only { gap: var(--space-3); }

@media (prefers-reduced-motion: reduce) {
  /* no hover scale, no knob swell, no thumb stretch (Slider's own reduced rule drops the stretch) */
  .sg-colorpick-swatch, .sg-colorpick-knob, .sg-colorpick-swatchbtn .sg-colorpick-chip { transition: none; }
  .sg-colorpick-swatch:hover:not(:disabled), .sg-colorpick-area.is-dragging .sg-colorpick-knob { transform: translate(-50%, -50%); }
  .sg-colorpick-swatch:hover:not(:disabled) { transform: none; }
}
@media (pointer: coarse) {
  /* 24px targets get a 44px reach with ::after, the look stays; the bars are 12px high and reach 44 above and below */
  .sg-colorpick-chip-btn::after, .sg-colorpick-swatchbtn::after { content: ""; position: absolute; inset: -10px; }
  .sg-colorpick-chip-btn { position: relative; }
  .sg-colorpick-swatchbtn.is-sm::after { inset: -10px; }
  .sg-colorpick-swatch::after { content: ""; position: absolute; inset: -10px -4px; }
  .sg-colorpick-swatches { row-gap: var(--space-3); }
  .sg-colorpick-bar::before { content: ""; position: absolute; left: 0; right: 0; top: -16px; bottom: -16px; }
}

/* ---------- Combobox: the recipe-A shell around a text box (and, when `multiple`, the chosen Tags); the list is the shared recipe-D / recipe-E panel ---------- */
.sg-cb.sg-field-box { min-width: 0; cursor: text; }
.sg-cb.is-open:not(.is-invalid) { border-color: var(--ink); }
.sg-cb.is-disabled { cursor: not-allowed; }
/* the input and, in a multiple box, the chips in front of it */
.sg-cb-field { flex: 1; min-width: 0; align-self: stretch; display: flex; align-items: center; }
.sg-cb-input { text-overflow: ellipsis; }
.sg-cb-input:disabled { cursor: not-allowed; }
/* the busy dots, the clear button and the arrow, at the right edge */
.sg-cb-tail { flex: none; align-self: stretch; display: flex; align-items: center; gap: var(--space-1); color: var(--ink-2); }
.sg-cb-chev { display: grid; place-items: center; width: 16px; height: 16px; cursor: pointer; }
.sg-cb-chev .sg-icon { width: 16px; height: 16px; transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-cb.is-open .sg-cb-chev .sg-icon { transform: rotate(180deg); }
.sg-cb.is-disabled .sg-cb-chev { cursor: not-allowed; }

/* multiple: chips wrap onto rows. One row is exactly the single-line height: 28px chips + 7px above and below + the 1px border = 44 (24 + 3 + 3 + 2 = 32 for sm).
   The text box keeps at least 64px so there is always somewhere to type; the busy dots, clear button and arrow stay level with the first row. */
.sg-cb--multi.sg-field-box.sg-field-box--multi { padding-top: 7px; padding-bottom: 7px; align-items: flex-start; }
.sg-cb--multi.sg-field-box.sg-field-box--multi.sg-field-box--sm { padding-top: 3px; padding-bottom: 3px; }
.sg-cb--multi .sg-cb-field { flex-wrap: wrap; gap: 4px 6px; align-self: auto; }
.sg-cb--multi .sg-field-input.sg-cb-input { flex: 1 1 64px; min-width: 64px; height: 28px; line-height: 28px; }
.sg-cb--multi.sg-field-box--sm .sg-field-input.sg-cb-input { height: 24px; line-height: 24px; }
.sg-cb--multi .sg-cb-tail { align-self: flex-start; height: 28px; }
.sg-cb--multi.sg-field-box--sm .sg-cb-tail { height: 24px; }
.sg-cb .sg-tag { flex: none; max-width: 100%; }

/* what the list says when there is nothing to pick */
.sg-cb-empty { display: grid; justify-items: center; gap: 2px; padding: var(--space-4) var(--space-3); text-align: center; text-wrap: balance; }
.sg-cb-empty-title { font-size: 15px; line-height: 22px; color: var(--ink); }
.sg-cb-empty-hint { font-size: 13px; line-height: 18px; color: var(--ink-2); }
.sg-cb-busy { color: var(--ink-2); margin-bottom: var(--space-1); }
.sg-cb-create .sg-menu-icon { color: var(--ink); }

@media (prefers-reduced-motion: reduce) {
  /* the arrow still turns over to show the list is open, it just does not turn slowly */
  .sg-cb-chev .sg-icon { transition: none; }
}
@media (pointer: coarse) {
  /* the 24px clear button and the chips' 20px remove buttons reach 44px through their own touch rules; in a 32px shell they sit above the shell's 6px strips */
  .sg-cb-clear, .sg-cb .sg-tag-x { position: relative; z-index: 2; }
  /* the arrow is a 28px box that closes an open list: its hit area is stretched to 44 x 44 (8px on every side) without changing how it looks.
     It sits above the 6px strips a 32px shell adds above and below itself (z-index 1), and below the clear button (z-index 2), so where the clear button overlaps it the clear button wins */
  .sg-cb-chev { position: relative; z-index: 1; width: 28px; height: 28px; margin-right: -6px; }
  .sg-cb-chev::after { content: ""; position: absolute; inset: -8px; }
}

/* ---------- CommandPalette (layer, scrim, stacking and the enter / exit motion come from Dialog.css) ---------- */
/* a quarter of the way down, 640 wide; the list scrolls, the search row and the hint row stay */
.sg-modal.sg-modal--top { align-items: flex-start; padding-top: 18vh; }
.sg-overlay.sg-modal-panel.sg-cmd { --sg-modal-w: 640px; max-height: min(560px, 100%); }

.sg-cmd-search { box-sizing: border-box; flex: none; display: flex; align-items: center; gap: var(--space-3); height: 52px; padding: 0 var(--space-4) 0 var(--space-5); border-bottom: 1px solid var(--line); }
.sg-cmd-search > .sg-icon { width: 20px; height: 20px; color: var(--ink-2); }
.sg-cmd-input { flex: 1; min-width: 0; height: 100%; padding: 0; margin: 0; border: 0; outline: none; background: none; font: inherit; font-size: 17px; line-height: 24px; color: var(--ink); caret-color: var(--ink); }
.sg-cmd-input::placeholder { color: var(--ink-2); opacity: 1; }
.sg-cmd-input:focus-visible { outline: none; }
.sg-cmd-busy { flex: none; color: var(--ink-2); }

/* results: option rows (recipe E), the description sits on the same line, quieter */
.sg-cmd-list { position: relative; flex: 0 1 auto; min-height: 0; overflow: auto; overscroll-behavior: contain; padding: var(--space-2); }
.sg-cmd-item { gap: var(--space-3); }
.sg-cmd-item[aria-selected="true"] { font-weight: 400; }
.sg-cmd-title { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-cmd-desc { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; line-height: 18px; color: var(--ink-2); }
.sg-cmd-item > .sg-menu-kbd { padding-inline-start: 0; }
.sg-cmd-empty { padding: var(--space-2); }
.sg-cmd-empty .sg-empty { max-width: none; }

/* searching: rows the size of result rows (36, 44 on touch; 12 on each side) with a 16px icon block and a title bar; the shimmer comes from .sg-skel */
.sg-cmd-skel-row { display: flex; align-items: center; gap: var(--space-3); height: 36px; padding: 0 var(--space-3); }
.sg-cmd-skel-icon { flex: none; width: 16px; height: 16px; border-radius: var(--radius-xs); }
.sg-cmd-skel-text { flex: none; width: 40%; }
.sg-cmd-skel-row:nth-child(2) .sg-cmd-skel-text { width: 30%; }
.sg-cmd-skel-row:nth-child(3) .sg-cmd-skel-text { width: 48%; }

/* the hint row: ↑↓ 选择 · ↵ 打开 · esc 关闭 */
.sg-cmd-foot { box-sizing: border-box; flex: none; display: flex; align-items: center; gap: var(--space-3); height: 40px; padding: 0 var(--space-5); border-top: 1px solid var(--line); font-size: 12px; line-height: 16px; color: var(--ink-2); }
.sg-cmd-hint { display: inline-flex; align-items: center; gap: var(--space-2); }
.sg-cmd-keys { display: inline-flex; align-items: center; gap: 2px; }
.sg-cmd-sep { color: var(--ink-3); }

@media (max-width: 639px) {
  .sg-modal.sg-modal--top { padding-top: calc(var(--space-4) + 8vh); }
  .sg-cmd-search { padding-left: var(--space-4); }
}
@media (prefers-reduced-motion: reduce) {
  .sg-cmd-item { transition-property: background-color, color, opacity; }
}
@media (pointer: coarse) {
  /* results are 44px rows on touch; there is no keyboard to hint at */
  .sg-cmd-item { min-height: 44px; }
  .sg-cmd-skel-row { height: 44px; }
  .sg-cmd-foot, .sg-cmd-item > .sg-menu-kbd { display: none; }
}

/* ---------- ContextMenu: the wrapper only; the menu is DropdownMenu's (.sg-ddmenu, recipe D panel + recipe E rows) ---------- */
/* a long press on iOS must open our menu, not the system callout */
.sg-ctxmenu { -webkit-touch-callout: none; }

@media (prefers-reduced-motion: reduce) {
  /* the menu fades in and out only (from .sg-overlay); the wrapper has no motion */
}
@media (pointer: coarse) {
  /* touch opens it by holding 500 ms: keep the browser from starting a text selection under the finger on the wrapper itself */
  .sg-ctxmenu { -webkit-user-select: none; user-select: none; }
}

/* ---------- CopyButton: icon variant = IconButton ghost with a cross-fading icon stack; button variant = Button glass with the word swapping in place ---------- */
.sg-copy { flex: none; }

/* icon: copy / check / x-circle sit in one grid cell. The old icon fades out and blurs 2px while the new one fades in */
.sg-copy-stack { display: inline-grid; place-items: center; }
.sg-copy-stack > .sg-icon { grid-area: 1 / 1; opacity: 0; filter: blur(2px);
  transition: opacity var(--duration-quick) var(--ease-liquid), filter var(--duration-quick) var(--ease-liquid); }
.sg-copy:not(.is-ok):not(.is-bad) .sg-copy-ico--copy,
.sg-copy.is-ok .sg-copy-ico--ok,
.sg-copy.is-bad .sg-copy-ico--bad { opacity: 1; filter: none; }
.sg-copy.is-ok .sg-copy-ico--ok { color: var(--status-good); }
.sg-copy.is-bad .sg-copy-ico--bad { color: var(--status-bad); }
/* the ghost IconButton nudges its icon on hover; the stack stays put */
.sg-copy.sg-iconbtn:not([disabled]):hover .sg-icon { transform: none; }

/* button: the three states (icon + word) share a cell and each is centred in it, so the width is the longest one and nothing jumps, and the icon stays 8 from its word */
.sg-copy-words { display: inline-grid; }
.sg-copy-word { grid-area: 1 / 1; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); opacity: 0; visibility: hidden;
  transition: opacity var(--duration-quick) var(--ease-liquid), visibility 0s linear var(--duration-quick); }
.sg-copy-word.is-on { opacity: 1; visibility: visible; transition: opacity var(--duration-quick) var(--ease-liquid), visibility 0s; }
.sg-copy--button.is-ok .sg-copy-word .sg-icon { color: var(--status-good); }
.sg-copy--button.is-bad .sg-copy-word .sg-icon { color: var(--status-bad); }

/* on a NebulaPanel: the same white hairline glass as IconButton's onNebula */
.sg-copy--button.is-nebula { background: rgba(255,255,255,.06); color: var(--on-nebula); border-color: rgba(255,255,255,.5); box-shadow: none; }
.sg-copy--button.is-nebula:not([disabled]):hover:not(:focus-visible) { background: rgba(255,255,255,.14); box-shadow: none; }
.sg-copy.is-nebula.is-ok .sg-copy-ico--ok, .sg-copy--button.is-nebula.is-ok .sg-copy-word .sg-icon { color: var(--glow-teal); }
.sg-copy.is-nebula.is-bad .sg-copy-ico--bad, .sg-copy--button.is-nebula.is-bad .sg-copy-word .sg-icon { color: var(--on-nebula-bad); }

@media (forced-colors: active) {
  .sg-copy-stack > .sg-icon { forced-color-adjust: auto; }
}
@media (prefers-reduced-motion: reduce) {
  /* the icon and the word switch at once: opacity only, no blur, no fade timing */
  .sg-copy-stack > .sg-icon { filter: none; transition: none; }
  .sg-copy-word { transition: none; }
  .sg-copy-word.is-on { transition: none; }
}
@media (pointer: coarse) {
  /* the icon button is IconButton's own xs / sm / md: core's coarse rules give xs and sm their 44px hit area; nothing to add */
  .sg-copy--icon { -webkit-tap-highlight-color: transparent; }
}

/* ---------- DatePicker: recipe A shell whose whole face is the trigger button; the popover is recipe D (radius-md) holding a Calendar ---------- */
/* min-width: 0 lets the shell shrink to its container (a flex / grid item defaults to min-content = the whole date), so the value's ellipsis can kick in */
.sg-dp.sg-field-box { padding: 0; min-width: 0; cursor: pointer; }
.sg-dp.is-open { border-color: var(--ink); }
.sg-dp-trigger { flex: 1; min-width: 0; height: 100%; display: flex; align-items: center; gap: var(--space-2); box-sizing: border-box; margin: 0; padding: 0 14px; border: 0; border-radius: inherit;
  background: none; color: inherit; font: inherit; font-size: 15px; text-align: start; cursor: pointer; outline: none; }
.sg-dp-trigger:disabled { cursor: not-allowed; }
.sg-dp.sg-field-box--sm .sg-dp-trigger { padding: 0 12px; font-size: 14px; }
.sg-dp-icon { width: 18px; height: 18px; color: var(--ink-2); }
.sg-dp-value { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-variant-numeric: tabular-nums; }
.sg-dp-value.is-placeholder { color: var(--ink-2); }
/* the 24px clear button keeps the same margin to the box edge above, below and to the right (the box is 1px bordered) */
.sg-dp-clear { flex: none; margin-right: calc((var(--control-md) - var(--control-xs)) / 2 - 1px); }
.sg-dp.sg-field-box--sm .sg-dp-clear { margin-right: calc((var(--control-sm) - var(--control-xs)) / 2 - 1px); }
.sg-dp.has-clear .sg-dp-trigger { padding-right: 0; }

.sg-dp-panel { width: max-content; }
.sg-dp-panel--side { display: flex; gap: var(--space-4); }
.sg-dp-shortcuts { display: flex; flex-direction: column; gap: 2px; flex: none; min-width: 120px; padding-right: var(--space-4); border-right: 1px solid var(--line); }
.sg-dp-short { white-space: nowrap; }
.sg-dp-short[aria-pressed="true"] { font-weight: 500; }
.sg-dp-short[aria-pressed="true"] .sg-menu-check { visibility: visible; }
.sg-dp-short:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
@media (hover: hover) {
  .sg-dp-short:hover:not([aria-disabled="true"]) { background: var(--state-hover); }
}
/* narrow screens: the shortcuts go on top as a 2 × 2 block */
@media (max-width: 520px) {
  .sg-dp-panel--side { flex-direction: column; gap: var(--space-3); }
  .sg-dp-shortcuts { display: grid; grid-template-columns: 1fr 1fr; gap: 2px var(--space-2); min-width: 0; padding: 0 0 var(--space-3); border-right: 0; border-bottom: 1px solid var(--line); }
}

@media (prefers-reduced-motion: reduce) {
  .sg-dp-short { transition-property: background-color, color, opacity; }
}
@media (pointer: coarse) {
  /* the 24px clear button reaches 44px through IconButton's own touch rule; the shortcuts are menu rows (44 high on touch) */
  .sg-dp-clear { position: relative; }
}

/* ---------- Dialog · also the shared modal layer of AlertDialog, Drawer and CommandPalette (.sg-modal*) ---------- */

/* the fixed layer that holds a panel: clicks fall through it to the scrim (.sg-scrim, from _primitives) except on the panel itself.
   The margin around the panel is never smaller than the notch / home-indicator inset (viewport-fit=cover pages); env() is 0 everywhere else. */
.sg-modal { position: fixed; inset: 0; z-index: var(--z-modal); box-sizing: border-box; display: flex; align-items: center; justify-content: center; pointer-events: none;
  padding: max(var(--space-6), env(safe-area-inset-top, 0px)) max(var(--space-4), env(safe-area-inset-right, 0px)) max(var(--space-6), env(safe-area-inset-bottom, 0px)) max(var(--space-4), env(safe-area-inset-left, 0px)); }

/* recipe D at radius-lg; padding lives on head / body / foot so the scrollbar sits on the panel edge */
.sg-overlay.sg-modal-panel { --sg-pad: var(--space-6); position: relative; display: flex; flex-direction: column; box-sizing: border-box; width: min(var(--sg-modal-w, 520px), 100%); max-width: 100%; max-height: 100%;
  padding: 0; overflow: hidden; pointer-events: auto; border-radius: var(--radius-lg); transform-origin: 50% 50%; }
.sg-dialog--sm { --sg-modal-w: 400px; }
.sg-dialog--md { --sg-modal-w: 520px; }
.sg-dialog--lg { --sg-modal-w: 720px; }

/* enter: scale .96 → 1 on a soft spring, with a blur-in that settles (two animations: the spring overshoots, a blur radius must not go negative) */
.sg-overlay.sg-modal-panel[data-state="open"] { animation: sg-modal-pop var(--duration-smooth) var(--ease-spring-soft) both, sg-modal-blur var(--duration-smooth) var(--ease-liquid) both; }
.sg-overlay.sg-modal-panel[data-state="closed"] { animation: sg-modal-out calc(var(--duration-smooth) * 2 / 3) var(--ease-exit) both; pointer-events: none; }
.sg-overlay.sg-modal-panel[data-instant][data-state="open"] { animation: none; }
@keyframes sg-modal-pop { from { transform: translateY(4px) scale(.96); } }
@keyframes sg-modal-blur { from { opacity: 0; filter: blur(6px); } }
@keyframes sg-modal-out { to { opacity: 0; transform: scale(.98); } }
@keyframes sg-modal-fade { from { opacity: 0; } }
@keyframes sg-modal-fade-out { to { opacity: 0; } }

/* head: title 24/30 (the `title` text style), description 15 ink-2 */
.sg-modal-head { flex: none; padding: var(--sg-pad) var(--sg-pad) 0; }
.sg-overlay.sg-modal-panel.is-closable .sg-modal-head { padding-right: calc(var(--sg-pad) + 28px); }
.sg-modal-title { margin: 0; color: var(--ink); overflow-wrap: anywhere; }
.sg-modal-desc { margin: var(--space-2) 0 0; color: var(--ink-2); overflow-wrap: anywhere; }
.sg-modal-title + .sg-modal-desc:last-child { margin-top: var(--space-2); }

/* body: the only part that scrolls; a hairline shows on an edge that has more content behind it (it appears and goes at once: colour is not an animated property here) */
.sg-modal-body { flex: 1 1 auto; min-height: 0; overflow: auto; overscroll-behavior: contain; box-sizing: border-box; padding: var(--space-4) var(--sg-pad);
  border-top: 1px solid transparent; border-bottom: 1px solid transparent; }
.sg-modal-body[data-top] { border-top-color: var(--line); }
.sg-modal-body[data-bottom] { border-bottom-color: var(--line); }
.sg-modal-body:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--focus-halo), inset 0 0 0 4px var(--focus-ring); }
.sg-modal-inner { min-width: 0; }
.sg-modal-panel.is-nohead .sg-modal-body { padding-top: var(--sg-pad); }
.sg-modal-panel.is-nohead.is-closable .sg-modal-body { padding-right: calc(var(--sg-pad) + 28px); }
.sg-modal-panel.is-nofoot .sg-modal-body { padding-bottom: var(--sg-pad); }

/* foot: secondary on the left, primary on the right */
.sg-modal-foot { flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--space-2); padding: var(--space-4) var(--sg-pad) var(--sg-pad); }
.sg-modal-panel.is-nobody .sg-modal-foot { padding-top: var(--sg-pad); }
.sg-modal-panel.is-nobody.is-nofoot .sg-modal-head { padding-bottom: var(--sg-pad); }
.sg-modal-foot .sg-btn.is-dim { opacity: var(--disabled); cursor: not-allowed; }

/* close: a 32px ghost button whose × lines up with the content edge and the title's first line */
.sg-overlay.sg-modal-panel .sg-modal-close { position: absolute; top: calc(var(--sg-pad) - 1px); right: calc(var(--sg-pad) - 8px); z-index: 2; }

/* phones: 16px left and right, tighter padding, the actions share the row */
@media (max-width: 639px) {
  .sg-modal { padding: max(var(--space-4), env(safe-area-inset-top, 0px)) max(var(--space-4), env(safe-area-inset-right, 0px)) max(var(--space-4), env(safe-area-inset-bottom, 0px)) max(var(--space-4), env(safe-area-inset-left, 0px)); }
  .sg-overlay.sg-modal-panel { --sg-pad: var(--space-5); }
}
@media (max-width: 479px) {
  .sg-modal-foot > .sg-btn { flex: 1 1 120px; justify-content: center; }
}

@media (prefers-reduced-motion: reduce) {
  .sg-overlay.sg-modal-panel[data-state="open"] { animation: sg-modal-fade var(--duration-base) var(--ease-liquid) both; }
  .sg-overlay.sg-modal-panel[data-state="closed"] { animation: sg-modal-fade-out calc(var(--duration-base) * 2 / 3) var(--ease-exit) both; }
  .sg-overlay.sg-modal-panel[data-instant][data-state="open"] { animation: none; }
}
@media (pointer: coarse) {
  /* nothing to add: the close button is an IconButton sm, whose 44px touch target comes from core; footer buttons are 44px high on touch already */
}

/* ---------- Divider: 1px line (a border, so Windows high-contrast mode keeps it); spacing from --sg-div-sp ---------- */
.sg-divider { --sg-div-sp: var(--space-4); --sg-div-line: var(--line); box-sizing: content-box; flex: none; color: var(--ink-2); }
.sg-divider.is-dashed { --sg-div-line: var(--line-strong); }
.sg-divider.is-nebula { --sg-div-line: rgba(255,255,255,.14); color: var(--on-nebula-2); }
.sg-divider.is-nebula.is-dashed { --sg-div-line: rgba(255,255,255,.32); }

/* horizontal, no text */
.sg-divider--h { display: block; height: 0; margin: var(--sg-div-sp) 0; border: 0; border-top: 1px solid var(--sg-div-line); }
.sg-divider--h.is-dashed { border-top-style: dashed; }
/* vertical: 1em tall, sits between inline items */
.sg-divider--v { display: inline-block; vertical-align: middle; align-self: center; width: 0; height: 1em; margin: 0 var(--sg-div-sp); border: 0; border-left: 1px solid var(--sg-div-line); }
.sg-divider--v.is-dashed { border-left-style: dashed; }

/* with text: line, words, line; 12 / 18 so Chinese has room */
.sg-divider--h.has-label { display: flex; align-items: center; gap: var(--space-3); height: auto; border-top: 0; font-size: 12px; line-height: 18px; font-weight: 400; }
.sg-divider-line { flex: 1 1 0; min-width: 16px; height: 0; border-top: 1px solid var(--sg-div-line); }
.sg-divider.is-dashed .sg-divider-line { border-top-style: dashed; }
.sg-divider.is-start .sg-divider-line:first-child { flex: 0 0 16px; min-width: 0; }
.sg-divider-text { flex: 0 1 auto; min-width: 0; overflow-wrap: anywhere; text-align: center; }

@media (forced-colors: active) {
  .sg-divider { --sg-div-line: CanvasText; }
}
@media (prefers-reduced-motion: reduce) {
  /* static: nothing moves, nothing to reduce */
}
@media (pointer: coarse) {
  /* decorative: never a tap target, nothing to enlarge */
}

/* ---------- DonutChart (uses the data-colour variables from the BarChart slice) ---------- */
@property --sg-donut-sweep { syntax: "<angle>"; inherits: false; initial-value: 360deg; }
.sg-donut { display: block; box-sizing: border-box; border-radius: var(--radius-xs); color: var(--sg-ch-ink, var(--ink)); font-family: var(--font-sans); }
.sg-donut.is-loading { opacity: .5; transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-donut-body { display: flex; flex-wrap: wrap; align-items: center; gap: 20px 32px; }
.sg-donut--stack .sg-donut-body { flex-direction: column; align-items: flex-start; }
.sg-donut--stack .sg-donut-legend { flex: none; width: 100%; min-width: 0; }
.sg-donut-ring { position: relative; flex: none; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.sg-donut-svg { display: block; overflow: visible; }
.sg-donut-seg { fill: none; stroke: var(--c); stroke-width: var(--t); stroke-linecap: butt; transform-origin: var(--o) var(--o);
  transition: transform var(--duration-base) var(--ease-liquid), opacity var(--duration-base) var(--ease-liquid); }
.sg-donut-svg[data-dim] .sg-donut-seg { opacity: .38; }
/* the segment under the pointer grows outward by 3px */
.sg-donut-svg .sg-donut-seg.is-cur { opacity: 1; transform: scale(var(--k)); }
.sg-donut-track { fill: none; stroke: color-mix(in srgb, var(--sg-ch-ink, var(--ink)) 8%, transparent); stroke-width: var(--t); }
/* data change: the ring sweeps in clockwise from 12 o'clock (never on the first render) */
@keyframes sg-donut-sweep { from { --sg-donut-sweep: 0deg; } to { --sg-donut-sweep: 360deg; } }
.sg-donut-svg.is-sweep { -webkit-mask-image: conic-gradient(black var(--sg-donut-sweep), transparent 0); mask-image: conic-gradient(black var(--sg-donut-sweep), transparent 0);
  animation: sg-donut-sweep var(--duration-slow) var(--ease-liquid) backwards; }
.sg-donut-center { position: absolute; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; text-align: center; pointer-events: none; }
.sg-donut-val { display: inline-flex; align-items: baseline; gap: 2px; max-width: 100%; white-space: nowrap; font-family: var(--font-display); color: var(--sg-ch-ink, var(--ink)); }
.sg-donut-val b { font-weight: 300; letter-spacing: -.02em; font-variant-numeric: normal; }
.sg-donut-val small { font-size: 12px; font-weight: 400; color: var(--sg-ch-ink-2, var(--ink-2)); }
.sg-donut-lab { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; line-height: 18px; color: var(--sg-ch-ink-2, var(--ink-2)); }
.sg-donut-none { font-size: 13px; color: var(--sg-ch-ink-2, var(--ink-2)); }
/* legend: shape dot · name · value · share (figures are tabular, so the column of shares lines up) */
.sg-donut-legend { flex: 1 1 200px; min-width: 200px; max-width: 360px; margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; }
.sg-donut-item { display: grid; grid-template-columns: 10px minmax(0, 1fr) auto 3.6em; align-items: center; gap: 0 10px; min-height: 32px; padding: 0 8px; margin: 0 -8px; border-radius: var(--radius-xs); font-size: 14px;
  transition: background-color var(--duration-instant); }
.sg-donut-item.is-cur { background: var(--state-hover); }
.sg-donut.sg-ch--nebula .sg-donut-item.is-cur { background: color-mix(in srgb, var(--sg-ch-ink) 10%, transparent); }
.sg-donut-item i { width: 10px; height: 10px; border-radius: 50%; background: var(--c); }
.sg-donut-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-donut-item b { font-weight: 500; font-variant-numeric: tabular-nums; text-align: right; }
.sg-donut-pct { font-size: 13px; text-align: right; color: var(--sg-ch-ink-2, var(--ink-2)); font-variant-numeric: tabular-nums; }
.sg-donut-item.is-zero .sg-donut-name, .sg-donut-item.is-zero b { color: var(--sg-ch-ink-2, var(--ink-2)); font-weight: 400; }
/* loading: a ring and three lines drawn as skeleton */
.sg-donut-skel { border-radius: 50%; flex: none;
  -webkit-mask-image: radial-gradient(circle closest-side, transparent calc(100% - var(--t)), black calc(100% - var(--t) + .5px)); mask-image: radial-gradient(circle closest-side, transparent calc(100% - var(--t)), black calc(100% - var(--t) + .5px)); }
.sg-donut-legend--skel { display: grid; gap: 14px; align-content: center; }

@media (prefers-reduced-motion: reduce) {
  .sg-donut-seg { transition-property: opacity !important; }
  .sg-donut-svg .sg-donut-seg.is-cur { transform: none; }
  .sg-donut-svg.is-sweep { animation: none !important; -webkit-mask-image: none; mask-image: none; }
}
@media (pointer: coarse) {
  /* a tap on a legend row highlights its segment: make the row a full 44px target */
  .sg-donut-item { min-height: 44px; }
}

/* ---------- DotText: round-dot Chinese, brand moments and covers only (digits: DotNumber) ---------- */
.sg-dottext { position: relative; display: inline-block; flex: none; vertical-align: -.12em; line-height: 0; white-space: nowrap; }
/* the canvas the dots are drawn on is decoration: the readable text is the .sg-sr node */
.sg-dottext-svg { position: absolute; display: block; overflow: visible; pointer-events: none; }
/* same two shadows as DotNumber's glow; on the wrapper so the halo is never clipped by the svg box */
.sg-dottext--glow { filter: drop-shadow(0 0 10px rgba(255,255,255,.55)) drop-shadow(0 0 2px rgba(255,255,255,.8)); }
/* only when the raster cannot be sampled (no canvas): plain text keeps the box and the meaning */
.sg-dottext-plain { position: absolute; inset: 0; font-family: var(--font-sans); font-size: .85em; font-weight: 400; line-height: 1; }
@keyframes sg-dottext-in { from { opacity: 0; transform: scale(.3); } to { opacity: 1; transform: scale(1); } }
.sg-dottext.is-anim .sg-dottext-svg path { transform-box: fill-box; transform-origin: 50% 50%; animation: sg-dottext-in var(--duration-smooth) var(--ease-spring-soft) both; }

@media (prefers-reduced-motion: reduce) {
  .sg-dottext .sg-dottext-svg path { animation: none !important; }
}
@media (pointer: coarse) {
  /* display only: nothing to tap, no hit area to extend */
}

/* ---------- Drawer (layer, head / body / foot, scrim and the nudge come from Dialog.css) ---------- */
/* 12px (space-3) from the viewport edges, more where the notch / home indicator needs it */
.sg-modal.sg-modal--drawer { align-items: stretch; justify-content: flex-end;
  padding: max(var(--space-3), env(safe-area-inset-top, 0px)) max(var(--space-3), env(safe-area-inset-right, 0px)) max(var(--space-3), env(safe-area-inset-bottom, 0px)) max(var(--space-3), env(safe-area-inset-left, 0px)); }
.sg-modal.sg-modal--drawer.sg-modal--left { justify-content: flex-start; }
.sg-overlay.sg-modal-panel.sg-drawer { height: 100%; transform-origin: 100% 50%; }
.sg-modal--left .sg-overlay.sg-modal-panel.sg-drawer { transform-origin: 0 50%; }
.sg-drawer--md { --sg-modal-w: 420px; }
.sg-drawer--lg { --sg-modal-w: 560px; }

/* slides in from its edge on the soft spring (the panel has a space-3 margin, plus the safe-area inset on that side, so it travels its own width plus both) */
.sg-modal--drawer .sg-overlay.sg-modal-panel.sg-drawer[data-state="open"] { animation: sg-drawer-in var(--duration-smooth) var(--ease-spring-soft) both; }
.sg-modal--drawer .sg-overlay.sg-modal-panel.sg-drawer[data-state="closed"] { animation: sg-drawer-out calc(var(--duration-smooth) * 2 / 3) var(--ease-exit) both; }
.sg-modal--left .sg-overlay.sg-modal-panel.sg-drawer[data-state="open"] { animation-name: sg-drawer-in-left; }
.sg-modal--left .sg-overlay.sg-modal-panel.sg-drawer[data-state="closed"] { animation-name: sg-drawer-out-left; }
.sg-modal--drawer .sg-overlay.sg-modal-panel.sg-drawer[data-instant][data-state="open"] { animation: none; }
@keyframes sg-drawer-in { from { transform: translateX(calc(100% + var(--space-3) + env(safe-area-inset-right, 0px))); } }
@keyframes sg-drawer-in-left { from { transform: translateX(calc(-100% - var(--space-3) - env(safe-area-inset-left, 0px))); } }
@keyframes sg-drawer-out { to { transform: translateX(calc(100% + var(--space-3) + env(safe-area-inset-right, 0px))); } }
@keyframes sg-drawer-out-left { to { transform: translateX(calc(-100% - var(--space-3) - env(safe-area-inset-left, 0px))); } }

@media (prefers-reduced-motion: reduce) {
  .sg-modal--drawer .sg-overlay.sg-modal-panel.sg-drawer[data-state="open"], .sg-modal--left .sg-overlay.sg-modal-panel.sg-drawer[data-state="open"] { animation: sg-modal-fade var(--duration-base) var(--ease-liquid) both; }
  .sg-modal--drawer .sg-overlay.sg-modal-panel.sg-drawer[data-state="closed"], .sg-modal--left .sg-overlay.sg-modal-panel.sg-drawer[data-state="closed"] { animation: sg-modal-fade-out calc(var(--duration-base) * 2 / 3) var(--ease-exit) both; }
  .sg-modal--drawer .sg-overlay.sg-modal-panel.sg-drawer[data-instant][data-state="open"] { animation: none; }
}
@media (pointer: coarse) {
  /* nothing to add: a drawer on a phone keeps the same margin, and the close button keeps its 44px reach from core */
}

/* ---------- DropdownMenu: recipe D panel (.sg-overlay--menu: radius-sm, 4 px, 180–320 wide) with recipe E rows (.sg-menu-*, from the shared primitives) ---------- */
.sg-ddmenu-anchor { display: contents; }
/* a long menu scrolls inside its capped height: rows must not shrink to fit */
.sg-ddmenu > .sg-menu-item, .sg-ddmenu > .sg-menu-label, .sg-ddmenu-group > .sg-menu-item { flex: none; }
.sg-ddmenu-group { display: flex; flex-direction: column; flex: none; }
/* keyboard moves scroll the active row into view with the panel's 4 px padding kept (Home / End show the top and bottom edges) */
.sg-ddmenu { scroll-padding-block: 4px; }
/* the row that owns the open submenu stays lit while the pointer is over the submenu */
.sg-ddmenu .sg-menu-item[aria-expanded="true"] { background: var(--state-hover); }
/* keyboard focus: the lit row also gets an inset ink ring, so the focus mark never depends on a 5 % tint alone */
.sg-ddmenu .sg-menu-item:focus-visible { box-shadow: inset 0 0 0 1.5px var(--focus-ring); }
.sg-ddmenu[data-nav="pointer"] .sg-menu-item:focus-visible { box-shadow: none; }   /* the pointer moved last: a hovered row is lit by the tint alone */
.sg-ddmenu .sg-menu-label:first-child { padding-top: 6px; }

@media (prefers-reduced-motion: reduce) {
  /* entrance and exit come from .sg-overlay (opacity only under reduced motion); rows already change colour only */
}
@media (pointer: coarse) {
  /* rows are 44 px high under a finger (from .sg-menu-item); group titles get matching air */
  .sg-ddmenu .sg-menu-label { padding-top: 12px; padding-bottom: 6px; }
}

/* ---------- FileDrop: a dashed zone (1.5px line-strong, radius-md, glass) and the surface-F list of files under it ---------- */
.sg-fd { display: grid; gap: var(--space-3); min-width: 0; }
.sg-drop { position: relative; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-3); min-height: 144px; padding: var(--space-6);
  border: 1.5px dashed var(--line-strong); border-radius: var(--radius-md); background: var(--glass); color: var(--ink); text-align: center; cursor: pointer;
  -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md));
  transition: border-color var(--duration-quick) var(--ease-liquid), background-color var(--duration-quick) var(--ease-liquid); }
.sg-drop:hover { border-color: var(--ink-2); }
/* a file is over the zone: ink edge, hover wash */
.sg-drop.is-over { border-color: var(--ink); background: linear-gradient(var(--state-hover), var(--state-hover)), var(--glass); }
.sg-drop.is-invalid { border-color: var(--status-bad); }
.sg-drop.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-drop.is-disabled:hover { border-color: var(--line-strong); }
.sg-field.is-disabled .sg-drop.is-disabled { opacity: 1; }
.sg-drop-icon { box-sizing: border-box; display: grid; place-items: center; width: 40px; height: 40px; flex: none; border-radius: 50%; background: var(--glass-strong); border: 1px solid var(--line); color: var(--ink); }
.sg-drop-icon .sg-icon { width: 20px; height: 20px; }
.sg-drop-body { display: grid; gap: 2px; min-width: 0; justify-items: center; }
.sg-drop-title { font-size: 15px; line-height: 22px; color: var(--ink); }
.sg-drop-pick { font-weight: 500; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.sg-drop-tap { display: none; font-weight: 500; }
.sg-drop-rule { font-size: 13px; line-height: 18px; color: var(--ink-2); text-wrap: balance; }
.sg-drop-input { display: none; }
/* compact: one row, for a form or a dialog */
.sg-drop.is-compact { flex-direction: row; justify-content: flex-start; gap: var(--space-3); min-height: 0; padding: var(--space-3) var(--space-4); text-align: start; }
.sg-drop.is-compact .sg-drop-icon { width: 32px; height: 32px; }
.sg-drop.is-compact .sg-drop-icon .sg-icon { width: 16px; height: 16px; }
.sg-drop.is-compact .sg-drop-body { justify-items: start; }

/* the file list */
.sg-file-list { list-style: none; margin: 0; padding: 0; border-radius: var(--radius-md); background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md)); overflow: hidden; }
.sg-file { display: flex; align-items: center; gap: var(--space-3); padding: 10px 10px 10px var(--space-4); }
.sg-file + .sg-file { border-top: 1px solid var(--line); }
.sg-file-icon { box-sizing: border-box; display: grid; place-items: center; flex: none; width: 32px; height: 32px; align-self: flex-start; border-radius: 50%; background: var(--glass-strong); border: 1px solid var(--line); color: var(--ink-2); }
.sg-file-icon .sg-icon { width: 16px; height: 16px; }
.sg-file-main { flex: 1; min-width: 0; display: grid; gap: 4px; }
.sg-file-name { display: flex; min-width: 0; font-size: 15px; line-height: 22px; color: var(--ink); }
.sg-file-head { min-width: 0; flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-file-tail { flex: none; white-space: pre; }
.sg-file-bar { margin: 2px 0; }
.sg-file-meta { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 13px; line-height: 18px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-file-size { white-space: nowrap; }
.sg-file-sep { color: var(--ink-3); }
.sg-file-state { white-space: nowrap; }
.sg-file.is-error .sg-file-state { color: var(--status-bad); }
.sg-file-error { margin: 0; font-size: 13px; line-height: 18px; color: var(--status-bad); text-wrap: pretty; }
.sg-file-actions { display: flex; align-items: center; flex: none; gap: 2px; }
.sg-file.is-error .sg-file-icon { color: var(--status-bad); }

@media (prefers-reduced-motion: reduce) {
  .sg-drop { transition-property: border-color, background-color, opacity; }
}
@media (pointer: coarse) {
  /* nothing to drag onto a phone: the zone says "tap", and the zone itself is far larger than 44px */
  .sg-drop-desk { display: none; }
  .sg-drop-tap { display: inline; }
  .sg-drop { min-height: 132px; }
  .sg-drop.is-compact { min-height: 68px; }
  /* the 32px row buttons keep their look and reach 44px through IconButton's own touch rule */
  .sg-file-actions .sg-iconbtn { position: relative; }
}

/* ---------- Footer: site = mist band (brand, columns of links, a line of small print); compact = one centred line ---------- */
.sg-footer { --sg-page-px: var(--space-4); box-sizing: border-box; width: 100%; color: var(--ink-2); font-size: 12px; line-height: 18px; }
@media (min-width: 640px) { .sg-footer { --sg-page-px: var(--space-6); } }
@media (min-width: 1024px) { .sg-footer { --sg-page-px: var(--space-8); } }
@media (min-width: 1440px) { .sg-footer { --sg-page-px: var(--space-12); } }
.sg-footer-in { box-sizing: border-box; max-width: calc(var(--sg-content-max, 1200px) + 2 * var(--sg-page-px)); margin-inline: auto; padding-inline: var(--sg-page-px); }

.sg-footer--site { background: var(--mist-100); border-top: 1px solid var(--line); padding-block: var(--space-8); }
@media (min-width: 640px) { .sg-footer--site { padding-block: var(--space-12); } }

/* brand on the left, the columns take the rest; below 640 the brand has a row of its own and the columns come two across */
.sg-footer-top { display: flex; flex-wrap: wrap; gap: var(--space-8) var(--space-12); }
.sg-footer-brand { flex: 1 1 240px; min-width: 0; max-width: 320px; color: var(--ink); font-size: 15px; line-height: 24px; }
.sg-footer-nav { flex: 4 1 560px; min-width: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: var(--space-8) var(--space-6); }
@media (max-width: 639px) { .sg-footer-brand { max-width: none; flex-basis: 100%; } .sg-footer-nav { flex-basis: 100%; grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.sg-footer-col { min-width: 0; }
.sg-footer-title { margin: 0 0 var(--space-3); font-size: 13px; line-height: 20px; font-weight: 500; letter-spacing: normal; color: var(--ink); }
.sg-footer-links { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
/* column links: 13 px, regular weight, so the 500-weight column title is the only strong thing in the column */
.sg-footer-links .sg-link--standalone { font-weight: 400; }

.sg-footer-bottom { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-6); }
.sg-footer-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); min-width: 0; }
.sg-footer-end { margin-inline-start: auto; }
.sg-footer-copy { white-space: nowrap; }
.sg-footer-extra { display: inline-flex; align-items: center; }
.sg-footer-in .sg-link--inline { font-size: 12px; line-height: 18px; }
@media (max-width: 639px) {
  .sg-footer-bottom, .sg-footer-meta { justify-content: center; text-align: center; }
  .sg-footer-end { margin-inline-start: 0; }
}

.sg-footer--compact { padding-block: var(--space-6); }
.sg-footer-line { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--space-1) 0; text-align: center; }
/* narrow: the line wraps, and a hairline that lands at the end or the start of a row would dangle, so the hairlines give way to plain gaps */
@media (max-width: 639px) { .sg-footer-line { column-gap: var(--space-4); } .sg-footer-line > .sg-divider { display: none; } }

@media (prefers-reduced-motion: reduce) {
  /* nothing in a footer moves */
}
@media (pointer: coarse) {
  /* column links and legal links get their 44px reach from Link on touch; the filing numbers are links in a sentence-like line and keep the text's own size */
  .sg-footer-links { gap: 2px; }
}

/* ---------- Form: fields stacked with space-5 between; no background of its own. The summary is an error Alert on top. ---------- */
.sg-form { display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }
/* the form stretches its children; a button (or a standalone link) placed straight in it keeps its own width. SegmentedControl does the same through its own width: fit-content. A block button still fills the row */
.sg-form > .sg-btn:not(.sg-btn--block), .sg-form > .sg-link--standalone { align-self: flex-start; }
.sg-form-summary-lead { margin: 0 0 var(--space-1); }
.sg-form-summary-list { display: grid; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
.sg-form-summary-list li { min-width: 0; overflow-wrap: anywhere; }

@media (prefers-reduced-motion: reduce) {
  /* nothing in the form itself moves; the summary Alert and the fields have their own reduced-motion rules */
}
@media (pointer: coarse) {
  /* the summary links are text inside a sentence-sized list: give each row a 44px band to tap */
  .sg-form-summary-list li { display: flex; align-items: center; min-height: 44px; }
  .sg-form-summary-list { gap: 0; }
}

/* ---------- ImageFrame: fixed-ratio frame, skeleton → fade-in, failure with retry ---------- */
.sg-imgframe { position: relative; display: block; width: 100%; max-width: 100%; box-sizing: border-box; margin: 0; padding: 0; border: 0; overflow: hidden; isolation: isolate;
  background: var(--mist-100); color: var(--ink-2); font: inherit; text-align: inherit; container-type: inline-size; -webkit-tap-highlight-color: transparent; }
.sg-imgframe.is-preview { cursor: zoom-in; }
.sg-imgframe-img { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; opacity: 0; -webkit-user-drag: none; user-select: none;
  transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-imgframe--contain .sg-imgframe-img { object-fit: contain; }
.sg-imgframe.is-loaded .sg-imgframe-img { opacity: 1; }
/* no ratio given: the picture sets the height (and the layout moves when it arrives; give a ratio, or width and height, to avoid that) */
.sg-imgframe.is-natural .sg-imgframe-img { position: relative; inset: auto; height: auto; }
.sg-imgframe.is-natural:not(.is-loaded) { min-height: 96px; }
.sg-imgframe.is-natural.is-failed { min-height: 120px; }

/* skeleton: the .sg-skel colour and sweep, behind the picture; it fades out when the picture has arrived */
.sg-imgframe-skel { position: absolute; inset: 0; z-index: 1; border-radius: 0; pointer-events: none;
  transition: opacity var(--duration-base) var(--ease-liquid), visibility 0s linear var(--duration-base); }
.sg-imgframe-skel.is-gone { opacity: 0; visibility: hidden; }
.sg-imgframe-skel.is-gone::after { animation: none; }
.sg-imgframe.is-instant .sg-imgframe-img, .sg-imgframe.is-instant .sg-imgframe-skel { transition: none; }

/* failure: mist-100, a 24px image mark, "图片加载失败", a text button to try again */
.sg-imgframe-fail { position: absolute; inset: 0; z-index: 2; box-shadow: inset 0 0 0 1px var(--line); border-radius: inherit; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-1); padding: var(--space-2); box-sizing: border-box; background: var(--mist-100); text-align: center; }
.sg-imgframe-failmsg { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); min-width: 0; }
.sg-imgframe-failicon { color: var(--ink-3); }
.sg-imgframe-failtext { font-size: 12px; line-height: 16px; color: var(--ink-2); }
.sg-imgframe-failtext:lang(zh) { line-height: 18px; }
.sg-imgframe-retry { position: relative; margin: 0; padding: 2px var(--space-1); border: 0; border-radius: var(--radius-xs); background: none; cursor: pointer; font: inherit; font-size: 12px; line-height: 16px; font-weight: 500; color: var(--ink);
  text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: var(--line-strong); -webkit-tap-highlight-color: transparent;
  transition: text-decoration-color var(--duration-quick) var(--ease-liquid), opacity var(--duration-instant); }
.sg-imgframe-retry:hover { text-decoration-color: var(--ink); }
.sg-imgframe-retry:active { opacity: .6; }
.sg-imgframe-retry:lang(zh) { line-height: 18px; }
@container (max-width: 139px) { .sg-imgframe-failtext { display: none; } }

/* caption: the frame becomes a <figure> */
.sg-imgframe-fig { display: block; margin: 0; min-width: 0; }
.sg-imgframe-cap { margin: var(--space-2) 0 0; font-size: 12px; line-height: 18px; color: var(--ink-2); }

/* ---------- ImageViewer: full-screen, on the nebula's deep colour so a light page does not wash the picture out ---------- */
.sg-modal.sg-viewer-wrap { padding: 0; }
.sg-overlay.sg-modal-panel.sg-viewer, .sg-overlay.sg-modal-panel.sg-viewer[data-state] { width: 100%; height: 100%; max-width: none; max-height: none; border: 0; border-radius: 0; overflow: hidden;
  background: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; animation: none; color: var(--on-nebula); }
.sg-viewer-root { position: absolute; inset: 0; overflow: hidden; user-select: none; -webkit-user-select: none; }
.sg-viewer-bg { position: absolute; inset: 0; background: color-mix(in srgb, var(--nebula-deep) 94%, transparent); opacity: var(--sg-bg, 1); }
.sg-viewer-chrome { opacity: var(--sg-bg, 1); }
/* the backdrop and the controls fade; the picture itself flies (script, from / to its thumbnail) */
.sg-viewer[data-state="open"] .sg-viewer-bg, .sg-viewer[data-state="open"] .sg-viewer-chrome { animation: sg-viewer-in var(--duration-base) var(--ease-liquid) backwards; }
.sg-viewer[data-state="closed"] .sg-viewer-bg, .sg-viewer[data-state="closed"] .sg-viewer-chrome { animation: sg-viewer-out calc(var(--duration-base) * 2 / 3) var(--ease-exit) forwards; }
.sg-viewer[data-instant] .sg-viewer-bg, .sg-viewer[data-instant] .sg-viewer-chrome { animation: none; }
@keyframes sg-viewer-in { from { opacity: 0; } }
@keyframes sg-viewer-out { to { opacity: 0; } }

.sg-viewer-stage { position: absolute; inset: 0; z-index: 1; overflow: hidden; touch-action: none; cursor: zoom-in; }
.sg-viewer-root.is-zoomed .sg-viewer-stage { cursor: grab; }
.sg-viewer-root.is-zoomed.is-dragging .sg-viewer-stage { cursor: grabbing; }
.sg-viewer-strip { display: flex; width: 100%; height: 100%; will-change: transform; }
.sg-viewer-slide { position: relative; flex: 0 0 100%; min-width: 0; height: 100%; box-sizing: border-box; padding: var(--space-6); }
.sg-viewer-root.has-cap .sg-viewer-slide { padding-bottom: 72px; }
.sg-viewer-pan { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; will-change: transform; }
.sg-viewer-img { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; -webkit-user-drag: none; user-select: none; }
.sg-viewer-fail { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); font-size: 13px; line-height: 18px; color: var(--on-nebula-2); }
.sg-viewer-wait { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; color: var(--on-nebula-2); }

/* the bar on top (count left, zoom out / in and close right), the arrows at the sides, the caption below */
.sg-viewer-top { position: absolute; top: 0; left: 0; right: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); box-sizing: border-box; pointer-events: none;
  padding: max(var(--space-3), env(safe-area-inset-top, 0px)) max(var(--space-4), env(safe-area-inset-right, 0px)) var(--space-3) max(var(--space-4), env(safe-area-inset-left, 0px)); }
.sg-viewer-top > * { pointer-events: auto; }
.sg-viewer-count { font-size: 13px; line-height: 18px; color: var(--on-nebula-2); font-variant-numeric: tabular-nums; }
.sg-viewer-tools { display: flex; gap: var(--space-2); }
.sg-viewer-nav { position: absolute; left: 0; right: 0; top: 50%; z-index: 2; display: flex; justify-content: space-between; box-sizing: border-box; pointer-events: none; transform: translateY(-50%);
  padding: 0 max(var(--space-4), env(safe-area-inset-right, 0px)) 0 max(var(--space-4), env(safe-area-inset-left, 0px)); }
.sg-viewer-nav > * { pointer-events: auto; }
.sg-viewer .sg-iconbtn[aria-disabled="true"] { opacity: var(--disabled); cursor: not-allowed; }
.sg-viewer .sg-iconbtn[aria-disabled="true"]:active { transform: none; }
.sg-viewer-cap { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; box-sizing: border-box; max-width: 720px; margin: 0 auto; pointer-events: none; text-align: center;
  padding: var(--space-3) var(--space-6) max(var(--space-4), env(safe-area-inset-bottom, 0px)); font-size: 13px; line-height: 18px; color: var(--on-nebula-2);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.sg-viewer-cap:lang(zh) { line-height: 20px; }

@media (max-width: 639px) {
  .sg-viewer-slide { padding: 0; }
  .sg-viewer-root.has-cap .sg-viewer-slide { padding-bottom: 64px; }
}
@media (prefers-reduced-motion: reduce) {
  /* no gliding between pictures, no zoom easing, no flying: the layer and the picture only fade (the script uses opacity-only keyframes) */
  .sg-viewer-strip, .sg-viewer-pan { transition: none !important; }
  .sg-imgframe-skel::after { display: none; }
}
@media (pointer: coarse) {
  /* swipe instead of arrows; the small buttons get the system's 44px hit area (xs / sm rules of IconButton); the retry link gets one too */
  .sg-viewer-nav { display: none; }
  .sg-viewer-slide { padding: 0; }
  .sg-viewer-root.has-cap .sg-viewer-slide { padding-bottom: 64px; }
  .sg-imgframe-retry::after { content: ""; position: absolute; inset: -14px -10px; }
}

/* ---------- InfiniteList: the caller's list, then one 52px status row; the sentinel (1px, invisible) sits under it ---------- */
.sg-infinite { position: relative; min-width: 0; }
.sg-infinite-sentinel { height: 1px; margin-top: -1px; opacity: 0; pointer-events: none; }
.sg-infinite-foot { display: flex; align-items: center; justify-content: center; gap: var(--space-2); box-sizing: border-box; min-height: 52px; padding: 0 var(--space-4); font-size: 13px; line-height: 18px; color: var(--ink-2); outline: none; }
.sg-infinite-foot .sg-divider { flex: 1 1 auto; width: 100%; margin: 0; }
.sg-infinite-foot.is-loading .sg-busy { color: var(--ink-2); }

/* ---------- PullToRefresh: the content is pulled down by --sg-ptr-d; a drop above it is stretched by the pull (registered properties, so they animate back on release) ---------- */
@property --sg-ptr-d { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --sg-ptr-p { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --sg-ptr-o { syntax: "<number>"; inherits: true; initial-value: 0; }
.sg-ptr { position: relative; min-width: 0; --sg-ptr-max: 128px; overscroll-behavior-y: contain;
  transition: --sg-ptr-d var(--duration-smooth) var(--ease-spring-soft), --sg-ptr-p var(--duration-smooth) var(--ease-spring-soft), --sg-ptr-o var(--duration-smooth) var(--ease-liquid); }
.sg-ptr[data-drag] { transition: none; }
/* a transform that stays on would trap position: fixed descendants, so it is only there while the content is away from the top */
.sg-ptr[data-moved] > .sg-ptr-content { transform: translateY(var(--sg-ptr-d)); }
.sg-ptr-content { position: relative; }
.sg-ptr-zone { position: absolute; z-index: 1; left: 0; right: 0; top: 0; height: var(--sg-ptr-max); pointer-events: none;
  clip-path: inset(0 0 calc(var(--sg-ptr-max) - var(--sg-ptr-d)) 0); }
.sg-ptr-ind { position: absolute; left: 0; right: 0; top: 0; display: flex; align-items: center; justify-content: center; gap: var(--space-2); height: 20px;
  font-size: 12px; line-height: 18px; color: var(--ink-2); opacity: var(--sg-ptr-o); transform: translateY(calc(var(--sg-ptr-d) / 2 - 10px)); }
.sg-ptr-drop { width: 20px; height: 20px; border-radius: 50%; background: var(--ink); transform-origin: 50% 0; transform: translateY(calc(var(--sg-ptr-p) * 4px)) scaleY(calc(1 + .35 * var(--sg-ptr-p))); }
.sg-ptr.is-ready .sg-ptr-drop { transform: none; transition: transform var(--duration-spring) var(--ease-spring-bouncy); }
.sg-ptr-ok { color: var(--status-good); }
.sg-ptr-bad { color: var(--status-bad); }
.sg-ptr-ind .sg-busy { color: var(--ink-2); }
/* keyboard and mouse: the same refresh as a button, only visible while it has focus */
.sg-ptr-kb { position: absolute; z-index: 2; top: var(--space-2); right: var(--space-2); }
.sg-ptr-kb:not(:focus-within) { width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.sg-ptr-kb .sg-btn { background: var(--glass-overlay); -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }

@media (prefers-reduced-motion: reduce) {
  /* the content still follows the finger; letting go jumps back, and the drop neither stretches nor bounces */
  .sg-ptr { transition: none; }
  .sg-ptr-drop, .sg-ptr.is-ready .sg-ptr-drop { transform: none; transition: none; }
}
@media (pointer: coarse) {
  /* the refresh button is only for focus; a finger pulls */
}

/* ---------- Kbd: the keycap itself (.sg-kbd) lives in the shared primitives; this only lines several caps up ---------- */
.sg-kbds { display: inline-flex; align-items: center; gap: 2px; vertical-align: middle; white-space: nowrap; }
/* inside running text the caps sit on the text's middle line instead of pushing the line box taller */
.sg-kbds > .sg-kbd { position: relative; }

/* on an ink button or a nebula panel the glass cap would vanish (light text on a light cap in the dark theme): take the surface's own text colour */
.sg-btn--ink .sg-kbd, .sg-btn--danger .sg-kbd, .sg-nebula .sg-kbd { background: color-mix(in srgb, currentColor 14%, transparent); border-color: color-mix(in srgb, currentColor 30%, transparent); box-shadow: none; color: inherit; }

/* nothing here moves and nothing here is a click target: the two shared tail sections stay empty */
@media (prefers-reduced-motion: reduce) { }
@media (pointer: coarse) { }

/* ---------- Link: inline = underlined in running text; standalone = its own line, underline draws in on hover ---------- */
.sg-link { color: var(--ink); text-decoration: none; cursor: pointer; border-radius: var(--radius-xs); -webkit-tap-highlight-color: transparent;
  transition: opacity var(--duration-instant), color var(--duration-quick) var(--ease-liquid), text-decoration-color var(--duration-quick) var(--ease-liquid); }
.sg-link:active { opacity: .6; }

/* inline: size and weight come from the sentence around it */
.sg-link--inline { text-decoration: underline; text-decoration-color: var(--line-strong); text-decoration-thickness: 1px; text-underline-offset: 3px; }
.sg-link--inline:hover { text-decoration-color: var(--ink); }
.sg-link--inline.is-muted { color: var(--ink-2); text-decoration-color: var(--line); }
.sg-link--inline.is-muted:hover { color: var(--ink); text-decoration-color: var(--ink-2); }
.sg-link--inline.is-nebula { color: var(--on-nebula); text-decoration-color: rgba(255,255,255,.4); }
.sg-link--inline.is-nebula:hover { text-decoration-color: var(--on-nebula); }
.sg-link--inline.is-nebula.is-muted { color: var(--on-nebula-2); }
.sg-link--inline.is-nebula.is-muted:hover { color: var(--on-nebula); }

/* standalone: 500 weight, no underline until hover; the underline is a 1px border so it survives high-contrast mode */
.sg-link--standalone { position: relative; display: inline-flex; align-items: center; gap: var(--space-1); font-size: 15px; line-height: 22px; font-weight: 500; }
.sg-link--standalone.sg-link--sm { font-size: 13px; line-height: 20px; }
.sg-link-text { position: relative; }
.sg-link-text::after { content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 0; border-top: 1px solid var(--ink); transform: scaleX(0); transform-origin: left center;
  transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-link-icon { transition: transform var(--duration-quick) var(--ease-liquid); }
@media (hover: hover) {
  .sg-link--standalone:hover .sg-link-text::after { transform: scaleX(1); }
  .sg-link--standalone:hover .sg-link-icon { transform: translateX(2px); }
}
.sg-link--standalone:focus-visible .sg-link-text::after { transform: scaleX(1); }
.sg-link--standalone.is-muted { color: var(--ink-2); }
.sg-link--standalone.is-muted:hover { color: var(--ink); }
.sg-link--standalone.is-muted .sg-link-text::after { border-top-color: var(--ink-2); }
.sg-link--standalone.is-nebula { color: var(--on-nebula); }
.sg-link--standalone.is-nebula .sg-link-text::after { border-top-color: var(--on-nebula); }
.sg-link--standalone.is-nebula.is-muted { color: var(--on-nebula-2); }
.sg-link--standalone.is-nebula.is-muted:hover { color: var(--on-nebula); }

/* the "opens in a new window" mark: 14px, after the words */
.sg-link-ext { width: 14px; height: 14px; margin-left: 2px; vertical-align: -2px; opacity: .8; }
.sg-link--standalone .sg-link-ext { margin-left: 0; vertical-align: baseline; }

/* disabled: a span, dimmed, out of the tab order */
.sg-link.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-link.is-disabled:active { opacity: var(--disabled); }

@media (prefers-reduced-motion: reduce) {
  /* the underline fades in instead of drawing across, the arrow stays put */
  .sg-link-text::after { transform: none; opacity: 0; transition-property: opacity; }
  .sg-link--standalone:hover .sg-link-text::after, .sg-link--standalone:focus-visible .sg-link-text::after { transform: none; opacity: 1; }
  .sg-link--standalone:hover .sg-link-icon { transform: none; }
}
@media (pointer: coarse) {
  /* a link on its own line is a 44px target; links inside a sentence keep the text's own size (WCAG 2.5.8 allows that) */
  .sg-link--standalone::after { content: ""; position: absolute; inset: -11px -6px; }
  .sg-link--standalone.sg-link--sm::after { inset: -12px -6px; }   /* 20px line + 24 = 44 */
}

/* ---------- List: recipe F surface, rows of row-md (52). The hairline between rows starts at the text, not at the row's left edge ---------- */
.sg-list { --sg-li-px: var(--space-4); --sg-li-lead: 32px; --sg-li-row: var(--row-md); min-width: 0; color: var(--ink); font-size: 15px; line-height: 22px; }
.sg-list--sm { --sg-li-lead: 24px; --sg-li-row: var(--row-sm); }
.sg-list--bare { --sg-li-px: 0px; }
.sg-list-title { margin: 0 0 var(--space-2); padding: 0 var(--space-4); font-size: 13px; line-height: 18px; font-weight: 500; color: var(--ink-2); }
.sg-list--bare .sg-list-title { padding: 0; }
.sg-list-footer { margin: var(--space-2) 0 0; padding: 0 var(--space-4); font-size: 13px; line-height: 18px; color: var(--ink-2); }
.sg-list--bare .sg-list-footer { padding: 0; }
.sg-list-box { display: block; margin: 0; padding: 0; list-style: none; overflow: hidden; border-radius: var(--radius-md); background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4); }
.sg-list--bare .sg-list-box { overflow: visible; border-radius: 0; background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }

.sg-listitem { position: relative; display: block; margin: 0; padding: 0; --sg-li-inset: var(--sg-li-px); }
.sg-listitem.has-lead { --sg-li-inset: calc(var(--sg-li-px) + var(--sg-li-lead) + var(--space-3)); }
.sg-listitem + .sg-listitem::before { content: ""; position: absolute; z-index: 1; top: 0; left: var(--sg-li-inset); right: 0; height: 1px; background: var(--line); pointer-events: none; }
.sg-listitem-main { position: relative; display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: var(--sg-li-row); box-sizing: border-box; margin: 0; padding: 8px var(--sg-li-px); border: 0; border-radius: 0; background: transparent;
  color: inherit; font: inherit; line-height: inherit; text-align: start; text-decoration: none; -webkit-tap-highlight-color: transparent; }
.sg-list--bare .sg-listitem-main { width: calc(100% + 24px); margin-inline: -12px; padding-inline: 12px; border-radius: var(--radius-xs); }
button.sg-listitem-main, a.sg-listitem-main { cursor: pointer; transition: background-color var(--duration-instant) var(--ease-liquid); }
button.sg-listitem-main:not(:disabled):hover, a.sg-listitem-main:not([aria-disabled="true"]):hover { background: var(--state-hover); }
button.sg-listitem-main:not(:disabled):active, a.sg-listitem-main:not([aria-disabled="true"]):active { background: var(--state-pressed); }
.sg-listitem-main.sg-focusable:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring), inset 0 0 0 4px var(--focus-halo); }
.sg-listitem.is-selected > .sg-listitem-main { background: var(--state-selected); }
.sg-listitem.is-selected > button.sg-listitem-main:not(:disabled):hover { background: linear-gradient(var(--state-hover), var(--state-hover)), var(--state-selected); }
.sg-listitem.is-disabled { opacity: var(--disabled); }
.sg-listitem.is-disabled > .sg-listitem-main { cursor: not-allowed; }

.sg-listitem-lead { flex: none; display: grid; place-items: center; width: var(--sg-li-lead); height: var(--sg-li-lead); }
.sg-listitem-icon { display: grid; place-items: center; width: var(--sg-li-lead); height: var(--sg-li-lead); border-radius: 50%; background: var(--glass-strong); border: 1px solid var(--line); box-sizing: border-box; color: var(--ink);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-listitem-icon .sg-icon { width: 16px; height: 16px; }
.sg-list--sm .sg-listitem-icon .sg-icon { width: 14px; height: 14px; }
.sg-listitem-text { flex: 1; min-width: 0; display: grid; }
.sg-listitem-title { font-size: 15px; line-height: 22px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-list--sm .sg-listitem-title { font-size: 14px; line-height: 20px; }
.sg-listitem-desc { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: 13px; line-height: 18px; color: var(--ink-2); }
.sg-listitem.is-danger .sg-listitem-title, .sg-listitem.is-danger .sg-listitem-icon { color: var(--status-bad); }
.sg-listitem-end { flex: none; display: inline-flex; align-items: center; gap: var(--space-2); max-width: 55%; color: var(--ink-2); }
.sg-listitem-value { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 15px; font-variant-numeric: tabular-nums; color: var(--ink-2); }
.sg-list--sm .sg-listitem-value { font-size: 14px; }
.sg-listitem-chev { width: 16px; height: 16px; flex: none; color: var(--ink-3); transition: transform var(--duration-base) var(--ease-liquid); }
@media (hover: hover) {
  .sg-listitem-main:not(:disabled):not([aria-disabled="true"]):hover .sg-listitem-chev { transform: translateX(2px); }
}

@media (prefers-reduced-motion: reduce) {
  button.sg-listitem-main, a.sg-listitem-main { transition-property: background-color, color, opacity; }
  .sg-listitem-chev { transition: none; }
  .sg-listitem-main:hover .sg-listitem-chev { transform: none !important; }
}
@media (pointer: coarse) {
  /* sm rows are 40px: a finger gets 44 */
  .sg-list--sm { --sg-li-row: 44px; }
}

/* ---------- LoginBlock: a recipe-F card (glass, blur-md, line, shadow-glass), at most 400 wide. Title, tabs, fields at space-4, agreement, one ink button, a 12px note, other ways. ---------- */
.sg-login { box-sizing: border-box; width: 100%; max-width: 400px; min-width: 0; color: var(--ink); }
.sg-login.sg-glass { padding: var(--space-6); border-radius: var(--radius-md); }
.sg-login-title { margin: 0 0 var(--space-5); color: var(--ink); }
.sg-login-tabs { margin-top: calc(var(--space-1) * -1); }
.sg-login-form { display: grid; gap: var(--space-4); margin: 0; min-width: 0; }
/* a field's one grid column may shrink below an input's natural width (a 360px phone) */
.sg-login-form .sg-field { grid-template-columns: minmax(0, 1fr); }
.sg-login > .sg-login-form { margin-top: 0; }
.sg-login-codebox { min-width: 0; }
.sg-login-coderow { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-2); align-items: start; }
.sg-login-forgot { display: flex; justify-content: flex-end; margin-top: calc(var(--space-2) * -1); }
.sg-login-alert { margin: 0; }
/* the one-line form error is compact: Alert has no size prop, so the padding and the words are tightened here */
.sg-login .sg-alert.sg-login-alert { padding: 10px var(--space-3); gap: var(--space-2); border-radius: var(--radius-sm); }
.sg-login .sg-alert.sg-login-alert .sg-alert-text { font-size: 13px; line-height: 20px; }
.sg-login .sg-alert.sg-login-alert .sg-alert-icon { width: 18px; height: 18px; margin-top: 1px; }
.sg-login-primary.sg-btn { margin-top: var(--space-1); }
.sg-login-hint { margin: calc(var(--space-2) * -1) 0 0; text-align: center; color: var(--ink-2); }
.sg-login-extra { display: grid; justify-items: center; }
.sg-login-social { margin-top: var(--space-6); }
.sg-login-qr { display: grid; justify-items: center; padding: var(--space-2) 0 var(--space-2); }
/* the code step */
.sg-login-step2 { gap: var(--space-3); }
.sg-login-step2 .sg-login-title { margin: var(--space-2) 0 0; }
.sg-login-back.sg-iconbtn { margin-left: calc(var(--space-2) * -1); justify-self: start; }
.sg-login-sent { margin: 0 0 var(--space-3); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-login-status { margin: 0; display: flex; align-items: center; gap: var(--space-2); color: var(--ink-2); }
.sg-login-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-1); }
.sg-login-resend.sg-btn { margin-left: calc(var(--space-3) * -1); padding-left: var(--space-3); }
.sg-login-docs { margin: 0; padding: 0 0 0 var(--space-4); display: grid; gap: var(--space-1); font-size: 15px; line-height: 22px; }

@media (max-width: 480px) {
  .sg-login.sg-glass { padding: var(--space-5); border-radius: var(--radius-lg); }
}
@media (prefers-reduced-motion: reduce) {
  /* nothing of its own moves: tabs, the shake and the veil follow their parts */
}
@media (pointer: coarse) {
  /* every control inside is already 44px or reaches it; nothing to enlarge here */
}

/* ---------- NavBar: 56 px top bar (+ top safe area): back · title · actions. Sticky: content scrolled under it turns its background into overlay glass. ---------- */
.sg-navbar { position: relative; isolation: isolate; box-sizing: border-box; height: calc(56px + env(safe-area-inset-top, 0px)); padding: env(safe-area-inset-top, 0px) var(--space-4) 0; color: var(--ink);
  display: grid; grid-template-columns: var(--sg-navbar-side, 0px) minmax(0, 1fr) var(--sg-navbar-side, 0px); align-items: center; column-gap: var(--space-2);
  --sg-badge-ring: var(--mist-000); }
.sg-navbar.is-start { grid-template-columns: auto minmax(0, 1fr) auto; }
/* left-aligned without a back button: the title starts at the page margin, no empty slot (and its gap) in front of it */
.sg-navbar.is-start.no-back { grid-template-columns: minmax(0, 1fr) auto; }
.sg-navbar.is-start.no-back .sg-navbar-start { display: none; }
.sg-navbar.is-sticky { position: sticky; top: -1px; z-index: var(--z-sticky); }
/* A sticky bar rests 1 px above the top of its scroll area, so once pinned its top pixel is cut off and the IntersectionObserver can tell "pinned" from "not scrolled into view yet".
   The bar keeps its 56 px (+ safe area) and takes that pixel out of its own padding, so the layout around it (a flex column, a grid row) is the same as without `sticky`;
   the glass layer reaches 1 px below the box to make up for the cut, so the pinned bar still shows 56 px of glass. The title sits half a pixel off either way. */
.sg-navbar.is-sticky { padding-top: calc(1px + env(safe-area-inset-top, 0px)); }
.sg-navbar-start, .sg-navbar-end { display: flex; align-items: center; gap: var(--space-2); min-width: 0; }
.sg-navbar-end { justify-content: flex-end; }
.sg-navbar-title { margin: 0; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink); }
.sg-navbar.is-start .sg-navbar-title { text-align: start; }
/* the glass layer: faded in only once content is under the bar (opacity is the one thing animated) */
.sg-navbar::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: 0;
  background: var(--glass-overlay); border-bottom: 1px solid var(--line);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4);
  transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-navbar.is-sticky::before { bottom: -1px; }   /* see above: the glass makes up for the pixel the pinned bar loses at the top */
.sg-navbar[data-stuck]::before { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  /* the glass still fades in and out (opacity is allowed); nothing moves */
  .sg-navbar::before { transition-duration: var(--duration-instant); }
}
@media (pointer: coarse) {
  /* the buttons are 44 px already; keep long titles from sliding under them */
  .sg-navbar-title { -webkit-tap-highlight-color: transparent; }
}

/* ---------- NavRail: 72 px glass side rail. The current item is a solid disc (recipe C) that slides on the soft spring. ---------- */
.sg-navrail { position: relative; box-sizing: border-box; width: 72px; height: 100%; flex: none; display: flex; flex-direction: column; align-items: center; gap: var(--space-3); padding: 14px 0;
  overflow-x: hidden; overflow-y: auto; scrollbar-width: none; border-radius: var(--radius-md); color: var(--ink);
  background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4);
  --sg-badge-ring: var(--mist-100); }   /* the ring that separates a badge from what it sits on: the glass over mist reads as mist-100 */
.sg-navrail::-webkit-scrollbar { display: none; }
.sg-navrail-brand { display: grid; place-items: center; width: 44px; height: 44px; flex: none; }
.sg-navrail-sep { width: 24px; height: 1px; flex: none; background: var(--line); }
.sg-navrail-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; align-items: center; gap: var(--space-2); }
.sg-navrail-li { display: flex; width: 44px; height: 44px; flex: none; }
.sg-navrail-foot { margin-top: auto; display: flex; flex-direction: column; align-items: center; gap: var(--space-3); }

.sg-navrail-item { position: relative; z-index: 1; box-sizing: border-box; display: grid; place-items: center; flex: none; width: 44px; height: 44px; margin: 0; padding: 0; border: 0; border-radius: var(--radius-pill);
  background: transparent; color: var(--ink-2); font: inherit; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--duration-instant), color var(--duration-base), transform var(--duration-quick) var(--ease-liquid); }
.sg-navrail-item:not(.is-current):not(.is-disabled):hover { background: var(--state-hover); color: var(--ink); }
.sg-navrail-item:not(.is-disabled):active { transform: scale(.92); }
/* on the solid disc: ink on white in the light theme, ink-inverse on the bright disc in the dark one */
.sg-navrail-item.is-current { color: var(--ink); color: light-dark(var(--ink), var(--ink-inverse)); }
/* disabled: the icon dims, not the whole item, so the focus ring (a disabled item can be focused: its tip says why) keeps its full strength */
.sg-navrail-item.is-disabled { cursor: not-allowed; }
.sg-navrail-item.is-disabled .sg-icon { opacity: var(--disabled); }
.sg-navrail-item .sg-icon { width: 22px; height: 22px; }

.sg-navrail-ind { position: absolute; z-index: 0; top: 0; left: 0; border-radius: var(--radius-pill); background: var(--solid); box-shadow: var(--shadow-lift); pointer-events: none;
  transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-navrail-ind.is-still { transition: none; }

@media (prefers-reduced-motion: reduce) {
  /* the disc jumps instead of gliding; the press does not shrink */
  .sg-navrail-item { transition-property: background-color, color, opacity !important; }
  .sg-navrail-ind { transition: none; }
}
@media (pointer: coarse) {
  /* every item is already 44 px; no double-tap zoom, no grey flash on press */
  .sg-navrail-item { touch-action: manipulation; }
}

/* ---------- NumberField: recipe-A shell, a 28px stepper column on the right, or − / + at both ends (layout="split") ---------- */
.sg-spin:not(.sg-spin--split) { padding-right: 0; }
.sg-spin-input { text-overflow: ellipsis; }
.sg-spin-steps { flex: none; box-sizing: border-box; align-self: stretch; display: flex; flex-direction: column; width: 28px; margin-left: 4px; border-left: 1px solid var(--line); }
.sg-spin-btn { position: relative; flex: 1 1 0; min-height: 0; display: grid; place-items: center; margin: 0; padding: 0; border: 0; background: transparent; color: var(--ink-2); font: inherit; cursor: pointer;
  -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-instant) var(--ease-liquid), color var(--duration-instant) var(--ease-liquid); }
.sg-spin-btn--up { border-top-right-radius: calc(var(--radius-sm) - 1px); }
.sg-spin-btn--down { border-bottom-right-radius: calc(var(--radius-sm) - 1px); box-shadow: inset 0 1px 0 var(--line); }
.sg-spin-btn .sg-icon { width: 14px; height: 14px; }
.sg-field-box--sm .sg-spin-btn .sg-icon { width: 12px; height: 12px; }
.sg-spin-btn:not(:disabled):active { background: var(--state-pressed); color: var(--ink); }
.sg-spin-btn:disabled { opacity: var(--disabled); cursor: not-allowed; }
@media (hover: hover) {
  .sg-spin-btn:not(:disabled):hover { background: var(--state-hover); color: var(--ink); }
}
/* split: ghost icon buttons inside the shell (32px in the 44 shell, 24px in the 32 shell), the number centred between them */
.sg-spin--split { padding: 0 5px; }
.sg-spin--split.sg-field-box--sm { padding: 0 3px; }
.sg-spin-mid { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center; gap: var(--space-1); height: 100%; }
.sg-spin--split .sg-spin-input { flex: none; max-width: 100%; text-align: center; }
.sg-spin--split .sg-field-prefix { margin-right: 0; }
.sg-spin-split-btn { flex: none; }

@media (prefers-reduced-motion: reduce) {
  .sg-spin-btn { transition-property: background-color, color, opacity; }
}
@media (pointer: coarse) {
  /* the two stacked halves are 21px tall and cannot each reach 44px: they reach 44px sideways, and layout="split" is the one to use on a phone */
  .sg-spin-btn::after { content: ""; position: absolute; top: 0; bottom: 0; left: -9px; right: -8px; }
  /* the sm shell's 6px strips above and below are painted after its children: keep the split buttons above them */
  .sg-spin--split .sg-spin-split-btn { z-index: 1; }
}

/* ---------- Pagination: page buttons are 32px circles (pills from 3 digits on); the current page is recipe C — solid + shadow-lift, and the pill glides on ease-spring-soft ---------- */
.sg-pager { display: block; color: var(--ink); font-size: 14px; line-height: 20px; }
.sg-pager-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-4); }
.sg-pager-side { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); min-width: 0; }
.sg-pager-total { color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
button.sg-pager-size { display: inline-flex; width: auto; gap: var(--space-1); padding: 0 8px 0 12px; font-size: 14px; color: var(--ink); cursor: pointer; }
.sg-pager-size-text { white-space: nowrap; font-variant-numeric: tabular-nums; }
.sg-pager-size .sg-icon { color: var(--ink-2); }
.sg-pager-nav { display: inline-flex; margin-inline-start: auto; align-items: center; gap: var(--space-1); max-width: 100%; }
.sg-pager-track { position: relative; min-width: 0; }
.sg-pager-list { display: flex; align-items: center; gap: var(--space-1); margin: 0; padding: 0; list-style: none; }
.sg-pager-list > li { display: flex; }
.sg-pager-page { position: relative; z-index: 1; box-sizing: border-box; min-width: 32px; height: 32px; margin: 0; padding: 0 6px; border: 0; border-radius: var(--radius-pill); background: transparent;
  color: var(--ink); font: inherit; font-size: 14px; line-height: 20px; font-variant-numeric: tabular-nums; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--duration-instant) var(--ease-liquid), transform var(--duration-quick) var(--ease-liquid); }
.sg-pager-page:hover { background: var(--state-hover); }
.sg-pager-page:active { transform: scale(.92); background: var(--state-pressed); }
/* the current page sits on the gliding pill, so it has no fill of its own; text must be dark on the white pill in both themes */
.sg-pager-page[aria-current="page"] { background: transparent; font-weight: 500; color: var(--ink); color: light-dark(var(--ink), var(--ink-inverse)); }
.sg-pager-page[aria-current="page"]:active { background: transparent; }
.sg-pager-ind { position: absolute; z-index: 0; top: 0; left: 0; height: 32px; border-radius: var(--radius-pill); background: var(--solid); box-shadow: var(--shadow-lift); pointer-events: none;
  transition: transform var(--duration-spring) var(--ease-spring-soft), width var(--duration-spring) var(--ease-spring-soft); }
.sg-pager-dots { align-items: center; justify-content: center; min-width: 32px; height: 32px; color: var(--ink-2); user-select: none; }
.sg-pager-dots .sg-icon { width: 16px; height: 16px; }
/* a step at the first / last page is dimmed on its own; when the whole pager is disabled the pager's own dimming is enough (no double fade) */
.sg-pager:not(.is-disabled) .sg-pager-step[aria-disabled="true"] { opacity: var(--disabled); }
.sg-pager-step[aria-disabled="true"] { cursor: not-allowed; }
.sg-pager-step[aria-disabled="true"]:hover { background: transparent; }
.sg-pager.is-disabled { opacity: var(--disabled); }
.sg-pager.is-disabled .sg-pager-page, .sg-pager.is-disabled .sg-pager-size { cursor: not-allowed; }
.sg-pager-compact { display: none; min-width: 64px; justify-content: center; font-variant-numeric: tabular-nums; color: var(--ink-2); white-space: nowrap; }
.sg-pager-compact b { font-weight: 500; color: var(--ink); }

/* phone width: only the arrows and "3 / 12". The window decides (a pager has no width of its own, so it cannot measure itself inside a flex row); compact / compact={false} force it either way */
@media (max-width: 479px) {
  .sg-pager:not(.is-full) .sg-pager-inner { justify-content: center; }
  .sg-pager:not(.is-full) .sg-pager-nav { margin-inline-start: 0; }
  .sg-pager:not(.is-full) .sg-pager-side, .sg-pager:not(.is-full) .sg-pager-track { display: none; }
  .sg-pager:not(.is-full) .sg-pager-compact { display: inline-flex; }
}
.sg-pager.is-compact .sg-pager-inner { justify-content: center; }
.sg-pager.is-compact .sg-pager-nav { margin-inline-start: 0; }
.sg-pager.is-compact .sg-pager-side, .sg-pager.is-compact .sg-pager-track { display: none; }
.sg-pager.is-compact .sg-pager-compact { display: inline-flex; }

@media (prefers-reduced-motion: reduce) {
  .sg-pager-ind { transition: none; }
  .sg-pager-page { transition-property: background-color, color, opacity; }
  .sg-pager-page:active { transform: none; }
}
@media (pointer: coarse) {
  /* 32px buttons keep their look and get a 44px target; the list gets a little more air so the targets barely overlap */
  .sg-pager-list { gap: var(--space-2); }
  .sg-pager-page::after { content: ""; position: absolute; inset: -6px; border-radius: var(--radius-pill); }
}

/* ---------- PasswordStrength: four 4px segments and a word, then the rules; opens with grid-template-rows when something is typed ---------- */
.sg-pwstrength { display: grid; grid-template-rows: 1fr; font-size: 12px; line-height: 16px; color: var(--ink-2); }
.sg-pwstrength:lang(zh) { line-height: 18px; }
.sg-pwstrength[data-state="open"] { animation: sg-pws-in var(--duration-smooth) var(--ease-spring-soft) both; }
.sg-pwstrength[data-state="closed"] { animation: sg-pws-out calc(var(--duration-smooth) * 2 / 3) var(--ease-exit) both; }
.sg-pwstrength[data-instant][data-state="open"] { animation: none; }
@keyframes sg-pws-in { from { grid-template-rows: 0fr; opacity: 0; } }
@keyframes sg-pws-out { to { grid-template-rows: 0fr; opacity: 0; } }
.sg-pws-inner { min-height: 0; overflow: hidden; }
.sg-pws-head { display: flex; align-items: center; gap: var(--space-3); padding-top: var(--space-2); }
.sg-pws-bars { flex: 1; min-width: 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; }
.sg-pws-seg { height: 4px; border-radius: var(--radius-pill); background: var(--mist-200); transition: background-color var(--duration-base) var(--ease-liquid); }
.sg-pws-seg[data-tone="bad"] { background: var(--status-bad); }
.sg-pws-seg[data-tone="warn"] { background: var(--status-warn); }
.sg-pws-seg[data-tone="good"] { background: var(--status-good); }
.sg-pws-word { flex: none; min-width: 5.5em; text-align: end; white-space: nowrap; color: var(--ink-2); }   /* room for the longest word, so the segments do not shift as the level changes */
.sg-pws-word b { font-weight: 500; color: var(--ink); }
.sg-pws-rules { list-style: none; margin: var(--space-2) 0 0; padding: 0; display: grid; gap: 4px; }
.sg-pws-rule { display: flex; align-items: center; gap: 6px; }
.sg-pws-ic { flex: none; width: 14px; height: 14px; color: var(--ink-3); }
.sg-pws-rule.is-met .sg-pws-ic { color: var(--status-good); }

@media (prefers-reduced-motion: reduce) {
  /* no growing, only fading; the fill changes colour */
  .sg-pwstrength[data-state="open"] { animation: sg-ov-fade var(--duration-base) var(--ease-liquid) both; }
  .sg-pwstrength[data-state="closed"] { animation: sg-ov-fade-out calc(var(--duration-base) * 2 / 3) var(--ease-exit) both; }
  .sg-pwstrength[data-instant][data-state="open"] { animation: none; }
}
@media (pointer: coarse) {
  /* nothing to tap here: the segments and the rule list are read-only */
}

/* ---------- PhoneField: recipe-A shell, the country-code button inside its left edge; the code list is a recipe-D panel with recipe-E rows ---------- */
/* the shell may be narrower than an input's natural width (a 390 wide phone): the one grid column shrinks instead of letting the shell run out of the Field */
.sg-field.sg-phone { grid-template-columns: minmax(0, 1fr); }
.sg-field-box.sg-phone-box { padding-left: 0; gap: 0; min-width: 0; }
.sg-field-box.sg-field-box--sm.sg-phone-box { padding-left: 0; }
.sg-phone-box .sg-field-input { padding-left: 0; }
.sg-phone-box .sg-phone-ok { margin-right: var(--space-2); }
/* the button is the box minus its two 1px borders high, flush with the left edge */
.sg-phone-code { flex: none; align-self: stretch; display: inline-flex; align-items: center; gap: 4px; margin: 0; padding: 0 8px 0 12px; border: 0;
  border-radius: calc(var(--radius-sm) - 1px) 0 0 calc(var(--radius-sm) - 1px); background: transparent; color: var(--ink); font: inherit; font-size: 15px; line-height: 1;
  font-variant-numeric: tabular-nums; cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-instant) var(--ease-liquid); }
.sg-field-box--sm .sg-phone-code { font-size: 14px; padding-left: 10px; }
.sg-phone-code .sg-icon { width: 14px; height: 14px; color: var(--ink-2); transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-phone-code:hover:not(:disabled) { background: var(--state-hover); }
.sg-phone-code:active:not(:disabled) { background: var(--state-pressed); }
.sg-phone-code:focus-visible { background: var(--state-hover); }
.sg-phone-code[aria-expanded="true"] .sg-icon { transform: rotate(180deg); }
.sg-phone-code:disabled { cursor: not-allowed; }
.sg-phone-box .sg-phone-sep { height: 20px; margin: 0 12px 0 0; }
.sg-field-box--sm.sg-phone-box .sg-phone-sep { height: 16px; margin-right: 10px; }
.sg-phone-box.is-open:not(.is-invalid) { border-color: var(--ink); }
.sg-phone-ok { flex: none; color: var(--status-good); }

/* the code panel: as wide as the box (at least 280), at most 320 high; the search box stays put and the list scrolls */
.sg-overlay.sg-phone-panel { display: flex; flex-direction: column; padding: 8px; overflow: hidden; width: max(280px, var(--sg-anchor-w, 280px)); max-width: var(--sg-avail-w, 100vw); border-radius: var(--radius-sm); }
.sg-phone-search { flex: none; padding: 0 0 8px; }
.sg-phone-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.sg-phone-opt-code { flex: none; color: var(--ink-2); font-size: 14px; font-weight: 400; font-variant-numeric: tabular-nums; }
.sg-phone-none { cursor: default; }
.sg-phone-none .sg-menu-title { color: var(--ink-2); white-space: normal; }

@media (prefers-reduced-motion: reduce) {
  /* the arrow still turns over to show the list is open, it just does not turn slowly */
  .sg-phone-code .sg-icon { transition: none; }
}
@media (pointer: coarse) {
  /* the 32px box keeps its 6px strips above and below; the code button reaches the same way */
  .sg-field-box--sm.sg-phone-box .sg-phone-code { position: relative; }
  .sg-field-box--sm.sg-phone-box .sg-phone-code::after { content: ""; position: absolute; inset: -7px 0; }
  .sg-phone-box > .sg-iconbtn { z-index: 1; }
}

/* ---------- PinInput: 44 x 52 cells in the recipe-A shell, the digit 22px tabular and centred ---------- */
/* 44px cells side by side; in a column narrower than 8 gaps + the cells they shrink together (down to 32px at 8 cells in a 300px column) instead of dropping one onto a second row */
.sg-pin { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 44px); justify-content: start; gap: var(--space-2); min-width: 0; }
.sg-pin-cell { display: block; width: 100%; min-width: 0; height: 52px; margin: 0; padding: 0; text-align: center; font: inherit; font-family: var(--font-sans); font-size: 22px; line-height: 1; font-weight: 400;
  font-variant-numeric: tabular-nums; color: var(--ink); caret-color: var(--ink); -webkit-appearance: none; appearance: none; outline: none; }
/* the digit is replaced, not edited, so the selection highlight on focus is only noise: the focus ring marks the cell */
.sg-pin-cell::selection { background: transparent; color: inherit; }
/* Urbanist's bullet is a speck; masked cells use the system bullet, same as TextField's password */
.sg-pin-cell.is-mask { font-family: system-ui, sans-serif; font-size: 32px; }
.sg-pin-cell::placeholder { color: var(--ink-3); }

@media (prefers-reduced-motion: reduce) {
  /* nothing here moves: the cell only changes border colour and ring */
  .sg-pin-cell { transition-property: border-color, box-shadow; }
}
@media (pointer: coarse) {
  /* every cell is already 44 x 52: no hit area to extend */
}

/* ---------- Popover: recipe D glass (from .sg-overlay--panel: radius-md, space-4 padding), non-modal ---------- */
.sg-popover-anchor { display: contents; }
.sg-popover { min-width: 200px; max-width: min(360px, var(--sg-avail-w, 100vw)); }
.sg-popover-title { margin: 0 0 var(--space-2); font-size: 17px; line-height: 24px; font-weight: 500; letter-spacing: normal; color: var(--ink); }
.sg-popover-title:lang(zh) { line-height: 26px; }
.sg-popover-body { font-size: 15px; line-height: 22px; color: var(--ink); }
.sg-popover-body:lang(zh) { line-height: 24px; }
/* the close button sits in the corner; the title leaves room for it */
.sg-popover-close { position: absolute; top: 16px; right: 11px; }
.sg-popover--titled .sg-popover-close { top: 17px; }
.sg-popover--closable.sg-popover--titled .sg-popover-title { padding-inline-end: var(--space-6); }
.sg-popover--closable:not(.sg-popover--titled) .sg-popover-body { padding-inline-end: var(--space-6); }

@media (prefers-reduced-motion: reduce) {
  /* entrance and exit come from .sg-overlay (opacity only under reduced motion); nothing else in a Popover moves */
}
@media (pointer: coarse) {
  /* the corner close button is an IconButton xs: core already gives it a 44 px hit area on touch */
  .sg-popover { min-width: min(200px, calc(100vw - 24px)); }
}

/* ---------- Progress: 14% ink track (SPEC says mist-200, which vanishes on a dark card: 1.07 : 1), ink or status fill, radius-pill. The fill is one full-width bar revealed by clip-path, so it grows without touching layout. ---------- */
.sg-progress, .sg-ring { --sg-track-bg: color-mix(in srgb, var(--ink) 14%, transparent); }
.sg-progress { --pc: var(--ink); --ph: 6px; display: block; width: 100%; color: var(--ink); }
.sg-progress--sm { --ph: 4px; }
.sg-progress.is-success { --pc: var(--status-good); }
.sg-progress.is-warning { --pc: var(--status-warn); }
.sg-progress.is-error { --pc: var(--status-bad); }
.sg-progress-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-2); font-size: 13px; line-height: 20px; }
.sg-progress-label { min-width: 0; font-weight: 500; color: var(--ink); }
.sg-progress-value { margin-inline-start: auto; flex: none; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sg-progress-track { position: relative; height: var(--ph); border-radius: var(--radius-pill); background: var(--sg-track-bg); overflow: hidden; }
.sg-progress-fill { position: absolute; inset: 0; border-radius: var(--radius-pill); background: var(--pc);
  clip-path: inset(0 calc(100% - var(--sg-v, 0%)) 0 0 round var(--radius-pill));
  transition: clip-path var(--duration-slow) var(--ease-liquid), background-color var(--duration-base) var(--ease-liquid); }
/* indeterminate: a soft-edged highlight glides to the far end and back (the track is 1 / 0.4 = 2.5 highlights wide, so the travel is 150% of its own width) */
.sg-progress.is-indeterminate .sg-progress-fill { right: auto; width: 40%; clip-path: none; transition: none; border-radius: 0;
  background: linear-gradient(90deg, transparent, var(--pc) 30%, var(--pc) 70%, transparent);
  animation: sg-progress-run calc(var(--duration-loop) * 3 / 8) var(--ease-in-out) infinite alternate; }
@keyframes sg-progress-run { from { transform: translateX(0); } to { transform: translateX(150%); } }

/* ---------- ProgressRing: 4px stroke, thin number + unit in the middle ---------- */
.sg-ring { --pc: var(--ink); position: relative; display: inline-grid; place-items: center; flex: none; width: var(--sg-ring-size, 64px); height: var(--sg-ring-size, 64px); color: var(--ink); vertical-align: middle; }
.sg-ring.is-success { --pc: var(--status-good); }
.sg-ring.is-warning { --pc: var(--status-warn); }
.sg-ring.is-error { --pc: var(--status-bad); }
.sg-ring-svg { display: block; grid-area: 1 / 1; overflow: visible; }
.sg-ring-track { stroke: var(--sg-track-bg); }
.sg-ring-fill { stroke: var(--pc); stroke-linecap: round; transform: rotate(-90deg); transform-origin: 50% 50%;
  transition: stroke-dasharray var(--duration-slow) var(--ease-liquid), opacity var(--duration-base) var(--ease-liquid), stroke var(--duration-base) var(--ease-liquid); }
.sg-ring.is-zero .sg-ring-fill { opacity: 0; }
.sg-ring.is-indeterminate .sg-ring-fill { transition: none; animation: sg-ring-spin calc(var(--duration-loop) / 4) linear infinite; }
@keyframes sg-ring-spin { from { transform: rotate(-90deg); } to { transform: rotate(270deg); } }
.sg-ring-center { grid-area: 1 / 1; display: flex; align-items: baseline; justify-content: center; gap: 2px; min-width: 0; font-variant-numeric: tabular-nums; white-space: nowrap; }
.sg-ring-n { font-family: var(--font-display); font-size: var(--sg-ring-n, 22px); line-height: 1; font-weight: 300; letter-spacing: -.02em; color: var(--ink); }
.sg-ring-u { font-size: max(10px, calc(var(--sg-ring-n, 22px) * .5)); line-height: 1; font-weight: 400; color: var(--ink-2); }

@media (prefers-reduced-motion: reduce) {
  .sg-progress-fill { transition-property: background-color; }
  .sg-ring-fill { transition-property: opacity, stroke; }
  /* no gliding highlight: the whole track carries a still diagonal stripe instead, and the ring shows a still quarter arc */
  .sg-progress.is-indeterminate .sg-progress-fill { animation: none; right: 0; width: auto; border-radius: var(--radius-pill);
    background: repeating-linear-gradient(135deg, var(--pc) 0 6px, color-mix(in srgb, var(--pc) 28%, transparent) 6px 12px); }
  .sg-ring.is-indeterminate .sg-ring-fill { animation: none; }
  .sg-ring-n.sg-blur-in { animation: none; }
}
@media (pointer: coarse) {
  /* progress is a readout, not a target: nothing to enlarge */
  .sg-progress, .sg-ring { touch-action: auto; }
}

/* ---------- Prose: long-text typesetting. Sizes are the type styles: sm = body-sm 13/18 (Chinese 20), md = body 15/22 (24), lg = prose 17/28 (30, serif by default).
   Elements are styled through :where(), so the specificity stays at one class; anything inside .sg-not-prose is left alone. The rules for Chinese (punctuation, spacing, 着重号) come from _typography ---------- */
.sg-prose { color: var(--ink); font-family: var(--font-sans); font-size: 15px; line-height: 22px; font-weight: 400; letter-spacing: normal; overflow-wrap: break-word; min-width: 0; }
.sg-prose:lang(zh) { line-height: 24px; }
.sg-prose--sm { font-size: 13px; line-height: 18px; }
.sg-prose--sm:lang(zh) { line-height: 20px; }
.sg-prose :where([lang|="zh"]) { line-height: 24px; }
.sg-prose--sm :where([lang|="zh"]) { line-height: 20px; }
.sg-prose--lg :where([lang|="zh"]) { line-height: 30px; }
.sg-prose--lg { font-family: var(--font-serif); font-size: 17px; line-height: 28px; }
.sg-prose--lg:lang(zh) { line-height: 30px; }
.sg-prose--serif { font-family: var(--font-serif); }
.sg-prose--sans { font-family: var(--font-sans); }
/* the measure: at most 36 em a line (36 Chinese characters) */
.sg-prose--measure { max-width: 36em; }

/* headings: h1 = title, h2 = heading, h3 = body size at 600, h4 = label; 2em above, .6em below */
.sg-prose :where(h1, h2, h3, h4, h5, h6):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: 2em 0 .6em; color: var(--ink); scroll-margin-top: var(--space-12); text-wrap: balance; }
.sg-prose :where(h1):not(:where(.sg-not-prose, .sg-not-prose *)) { font-size: 24px; line-height: 30px; font-weight: 400; letter-spacing: -0.01em; }
.sg-prose :where(h1):lang(zh):not(:where(.sg-not-prose, .sg-not-prose *)) { line-height: 32px; letter-spacing: 0; }
.sg-prose :where(h2):not(:where(.sg-not-prose, .sg-not-prose *)) { font-size: 17px; line-height: 24px; font-weight: 500; }
.sg-prose :where(h2):lang(zh):not(:where(.sg-not-prose, .sg-not-prose *)) { line-height: 26px; }
.sg-prose :where(h3, h5, h6):not(:where(.sg-not-prose, .sg-not-prose *)) { font-size: inherit; line-height: inherit; font-weight: 600; }
.sg-prose :where(h4):not(:where(.sg-not-prose, .sg-not-prose *)) { font-size: 13px; line-height: 18px; font-weight: 500; }
.sg-prose :where(h4):lang(zh):not(:where(.sg-not-prose, .sg-not-prose *)) { line-height: 20px; }
.sg-prose > :where(:first-child):not(:where(.sg-not-prose, .sg-not-prose *)) { margin-top: 0; }
.sg-prose > :where(:last-child):not(:where(.sg-not-prose, .sg-not-prose *)) { margin-bottom: 0; }

/* paragraphs and lists: 1em between; lists indent 1.5em, markers ink-2, numbers tabular */
.sg-prose :where(p, dl, figure):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: 1em 0; }
.sg-prose :where(ul, ol):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: 1em 0; padding: 0 0 0 1.5em; }
.sg-prose :where(ul):not(:where(.sg-not-prose, .sg-not-prose *)) { list-style: disc; }
.sg-prose :where(ol):not(:where(.sg-not-prose, .sg-not-prose *)) { list-style: decimal; }
.sg-prose :where(li):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: .35em 0; padding-left: .25em; }
.sg-prose :where(li)::marker { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-prose :where(li > ul, li > ol):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: .35em 0; }
.sg-prose :where(dt):not(:where(.sg-not-prose, .sg-not-prose *)) { margin-top: 1em; font-weight: 500; }
.sg-prose :where(dd):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: .25em 0 0; color: var(--ink-2); }
.sg-prose :where(strong, b):not(:where(.sg-not-prose, .sg-not-prose *)) { font-weight: 600; }
.sg-prose :where(del):not(:where(.sg-not-prose, .sg-not-prose *)) { color: var(--ink-2); }

/* quote: a 2px line-strong rule, 16 in, ink-2 */
.sg-prose :where(blockquote):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: 1.25em 0; padding: 0 0 0 var(--space-4); border-left: 2px solid var(--line-strong); color: var(--ink-2); }
.sg-prose :where(blockquote > :first-child):not(:where(.sg-not-prose, .sg-not-prose *)) { margin-top: 0; }
.sg-prose :where(blockquote > :last-child):not(:where(.sg-not-prose, .sg-not-prose *)) { margin-bottom: 0; }
/* a rule: Divider's hairline */
.sg-prose :where(hr):not(:where(.sg-not-prose, .sg-not-prose *)) { height: 0; margin: 2em 0; border: 0; border-top: 1px solid var(--line); }

/* links: Link inline (underline 1px, offset 3, line-strong → ink on hover) */
.sg-prose :where(a):not(:where(.sg-not-prose, .sg-not-prose *)) { color: inherit; text-decoration: underline; text-decoration-color: var(--line-strong); text-decoration-thickness: 1px; text-underline-offset: 3px; border-radius: var(--radius-xs);
  transition: text-decoration-color var(--duration-quick) var(--ease-liquid); }
.sg-prose :where(a:hover):not(:where(.sg-not-prose, .sg-not-prose *)) { text-decoration-color: var(--ink); }
.sg-prose :where(a:focus-visible):not(:where(.sg-not-prose, .sg-not-prose *)) { outline: none; box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }

/* code: inline = Geist Mono .9em on mist-100 with a hairline; a block = CodeBlock's static look (use the CodeBlock component when it needs a copy button) */
.sg-prose :where(code, kbd, samp):not(:where(.sg-not-prose, .sg-not-prose *)) { font-family: var(--font-mono); font-variant-ligatures: none; }
.sg-prose :where(:not(pre) > code):not(:where(.sg-not-prose, .sg-not-prose *)) { padding: .1em .35em; font-size: .9em; background: var(--mist-100); border: 1px solid var(--line); border-radius: var(--radius-xs); overflow-wrap: anywhere; }
.sg-prose :where(pre):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: 1.25em 0; padding: var(--space-3) var(--space-4); overflow-x: auto; background: var(--mist-100); border: 1px solid var(--line); border-radius: var(--radius-sm);
  font-family: var(--font-mono); font-size: 13px; line-height: 20px; tab-size: 2; color: var(--ink); }
.sg-prose :where(pre code):not(:where(.sg-not-prose, .sg-not-prose *)) { padding: 0; font-size: inherit; background: none; border: 0; border-radius: 0; white-space: pre; overflow-wrap: normal; }
/* keys: the .sg-kbd keycap */
.sg-prose :where(kbd):not(:where(.sg-not-prose, .sg-not-prose *)) { display: inline-grid; place-items: center; box-sizing: border-box; min-width: 20px; height: 20px; padding: 0 5px; vertical-align: .08em;
  border-radius: calc(var(--radius-xs) / 2); border: 1px solid var(--line); background: var(--glass-strong); box-shadow: inset 0 -1px 0 var(--line);
  font-size: 11px; line-height: 1; font-weight: 500; color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sg-prose :where(kbd[data-sym]):not(:where(.sg-not-prose, .sg-not-prose *)) { font-family: system-ui, -apple-system, "Segoe UI Symbol", sans-serif; font-weight: 400; }
.sg-prose :where(mark):not(:where(.sg-not-prose, .sg-not-prose *)) { padding: 0 .15em; color: inherit; background: var(--state-selected); border-radius: 2px; }

/* tables: header 13 / 500 ink-2, a hairline under every row, numbers in tabular figures; a right-aligned column is align="right" (or .sg-prose-num) */
.sg-prose :where(table):not(:where(.sg-not-prose, .sg-not-prose *)) { width: 100%; margin: 1.25em 0; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.sg-prose :where(th, td):not(:where(.sg-not-prose, .sg-not-prose *)) { padding: 10px var(--space-3); border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.sg-prose :where(th):not(:where(.sg-not-prose, .sg-not-prose *)) { font-size: 13px; line-height: 18px; font-weight: 500; color: var(--ink-2); }
.sg-prose :where(th):lang(zh):not(:where(.sg-not-prose, .sg-not-prose *)) { line-height: 20px; }
.sg-prose :where(th:first-child, td:first-child):not(:where(.sg-not-prose, .sg-not-prose *)) { padding-left: 0; }
.sg-prose :where(th:last-child, td:last-child):not(:where(.sg-not-prose, .sg-not-prose *)) { padding-right: 0; }
.sg-prose :where([align="right"], .sg-prose-num):not(:where(.sg-not-prose, .sg-not-prose *)) { text-align: right; }
.sg-prose :where(caption):not(:where(.sg-not-prose, .sg-not-prose *)) { padding: 0 0 var(--space-2); text-align: left; font-size: 12px; line-height: 18px; color: var(--ink-2); caption-side: top; }
/* a wide table: the renderer wraps it in <div class="sg-prose-scroll" tabindex="0">; the wrapper scrolls sideways and fades at the ends that have more (CSS scroll-driven; without support it simply scrolls) */
.sg-prose :where(.sg-prose-scroll):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: 1.25em 0; overflow-x: auto; scrollbar-width: thin; border-radius: var(--radius-xs); }
.sg-prose :where(.sg-prose-scroll > table):not(:where(.sg-not-prose, .sg-not-prose *)) { min-width: max-content; margin: 0; }
.sg-prose .sg-prose-scroll:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
@property --sg-pf-l { syntax: '<length>'; inherits: false; initial-value: 0px; }
@property --sg-pf-r { syntax: '<length>'; inherits: false; initial-value: 0px; }
@keyframes sg-prose-fade-l { from { --sg-pf-l: 0px; } to { --sg-pf-l: 24px; } }
@keyframes sg-prose-fade-r { from { --sg-pf-r: 24px; } to { --sg-pf-r: 0px; } }
@supports (animation-timeline: scroll(x self)) {
  .sg-prose .sg-prose-scroll { animation: sg-prose-fade-l linear both, sg-prose-fade-r linear both; animation-timeline: scroll(x self), scroll(x self); animation-range: 0px 24px, calc(100% - 24px) 100%;
    -webkit-mask-image: linear-gradient(to right, transparent 0, black var(--sg-pf-l), black calc(100% - var(--sg-pf-r)), transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, black var(--sg-pf-l), black calc(100% - var(--sg-pf-r)), transparent 100%); }
}

/* pictures and captions */
.sg-prose :where(img, video):not(:where(.sg-not-prose, .sg-not-prose *)) { max-width: 100%; height: auto; border-radius: var(--radius-sm); }
.sg-prose :where(figcaption):not(:where(.sg-not-prose, .sg-not-prose *)) { margin-top: var(--space-2); font-size: 12px; line-height: 18px; color: var(--ink-2); }
.sg-prose :where(figure):not(:where(.sg-not-prose, .sg-not-prose *)) { margin: 1.5em 0; }

@media (prefers-reduced-motion: reduce) {
  /* nothing here moves except the link underline colour, which keeps its (colour-only) change */
  .sg-prose :where(a) { transition: none; }
}
@media (pointer: coarse) {
  /* links in running text are text, not buttons: they keep their size (WCAG 2.5.8 exempts inline links); the scroll wrapper is a swipe area */
  .sg-prose :where(a) { text-underline-offset: 4px; }
}

/* ---------- QRCode: dark modules on a light plate in BOTH themes (the one place solid is not "the selected thing": a reader cannot decode light-on-dark).
   Over it, loading / expired / scanned sit on a glass-overlay veil that blurs the code behind. ---------- */
.sg-qr { display: inline-flex; flex-direction: column; align-items: center; gap: var(--space-3); max-width: 100%; box-sizing: border-box; }
.sg-qr-box { position: relative; flex: none; max-width: 100%; }
.sg-qr-face { position: relative; box-sizing: border-box; width: 100%; height: 100%; display: grid; place-items: center; overflow: hidden;
  background: var(--solid); border: 1px solid var(--line); border-radius: var(--radius-sm); }
.sg-qr-svg { display: block; fill: var(--nebula-deep); flex: none; }
/* the mark over the middle: a solid rounded square, an odd number of modules across, about 9% of the code */
.sg-qr-icon { position: absolute; left: 50%; top: 50%; translate: -50% -50%; box-sizing: border-box; display: grid; place-items: center; padding: 10%; overflow: hidden;
  background: var(--solid); border-radius: min(var(--radius-xs), 22%); color: var(--nebula-deep); }
.sg-qr-icon > * { max-width: 100%; max-height: 100%; }
.sg-qr-ov { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; border-radius: var(--radius-sm); border: 1px solid var(--line);
  background: var(--glass-overlay); -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm));
  opacity: 0; visibility: hidden; pointer-events: none; transition: opacity calc(var(--duration-base) * 2 / 3) var(--ease-exit), visibility 0s linear calc(var(--duration-base) * 2 / 3); }
.sg-qr-ov[data-on="true"] { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity var(--duration-base) var(--ease-liquid), visibility 0s; }
.sg-qr-ov-in { display: grid; justify-items: center; gap: var(--space-2); padding: var(--space-3); color: var(--ink-2); }
.sg-qr-title { font-size: 13px; line-height: 20px; font-weight: 500; color: var(--ink); }
.sg-qr-sub { font-size: 12px; line-height: 18px; color: var(--ink-2); }
.sg-qr-ok { width: 24px; height: 24px; color: var(--status-good); }
.sg-qr-cap { margin: 0; max-width: 100%; text-align: center; font-size: 13px; line-height: 20px; color: var(--ink-2); }

@media (prefers-reduced-motion: reduce) {
  /* the veil switches on and off without fading */
  .sg-qr-ov, .sg-qr-ov[data-on="true"] { transition: none; }
}
@media (pointer: coarse) {
  /* the one control, the refresh Button sm, reaches 44px through Button's own touch rule */
}

/* ---------- RadioGroup: 20px circle (recipe B), or a glass card that gets an ink outline and a tick when chosen.
   Every "chosen" style reads the native :checked, never a class: a Radio outside a group is not controlled by React, and form.reset() or a sibling radio changes it too. ---------- */
.sg-radio-group { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); min-width: 0; }
.sg-radio-group--row { flex-direction: row; flex-wrap: wrap; align-items: flex-start; gap: var(--space-2) var(--space-6); }
.sg-radio-group--card { display: grid; grid-template-columns: minmax(0, 1fr); align-items: stretch; gap: var(--space-3); }
.sg-radio-group--card.sg-radio-group--row { grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); }

.sg-radio { position: relative; display: inline-grid; grid-template-columns: 20px minmax(0, 1fr); column-gap: var(--space-3); align-items: start; max-width: 100%; min-height: 24px; cursor: pointer;
  color: var(--ink); font-size: 15px; line-height: 22px; -webkit-tap-highlight-color: transparent; }
.sg-radio.is-bare { grid-template-columns: 20px; min-height: 20px; }
.sg-radio--sm { column-gap: var(--space-2); font-size: 14px; line-height: 20px; min-height: 20px; }
.sg-radio-input { position: absolute; z-index: 1; left: 0; top: 1px; width: 20px; height: 20px; margin: 0; opacity: 0; cursor: inherit; }
.sg-radio--sm .sg-radio-input { top: 0; }
.sg-radio-mark { position: relative; grid-column: 1; grid-row: 1; margin-top: 1px; width: 20px; height: 20px; box-sizing: border-box; display: grid; place-items: center; flex: none;
  border-radius: 50%; border: 1.5px solid var(--line-strong); background: var(--glass-strong);
  transition: border-color var(--duration-quick) var(--ease-liquid), box-shadow var(--duration-quick) var(--ease-liquid), background-color var(--duration-quick) var(--ease-liquid), transform var(--duration-quick) var(--ease-liquid); }
.sg-radio--sm .sg-radio-mark { margin-top: 0; }
.sg-radio-input:checked ~ .sg-radio-mark { border-color: var(--ink); }
/* the dot pops in on a bouncy spring; leaving takes 2/3 of that, ease-exit */
.sg-radio-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ink); transform: scale(0);
  transition: transform calc(var(--duration-spring) * 2 / 3) var(--ease-exit); }
.sg-radio-input:checked ~ .sg-radio-mark .sg-radio-dot { transform: scale(1); transition: transform var(--duration-spring) var(--ease-spring-bouncy); }

.sg-radio-text, .sg-radio-body { grid-column: 2; display: grid; min-width: 0; }
.sg-radio-title { overflow-wrap: anywhere; }
.sg-radio-hint { font-size: 13px; line-height: 18px; color: var(--ink-2); }
.sg-radio--sm .sg-radio-hint { font-size: 12px; line-height: 16px; }

@media (hover: hover) {
  .sg-radio:not(.is-disabled):hover .sg-radio-mark { box-shadow: 0 0 0 6px var(--state-hover); }
  .sg-radio:not(.is-disabled):hover .sg-radio-input:not(:checked) ~ .sg-radio-mark { border-color: var(--ink-2); }
}
.sg-radio:not(.is-disabled):active .sg-radio-mark { transform: scale(.92); box-shadow: 0 0 0 6px var(--state-pressed); }
.sg-radio-input:focus-visible + .sg-radio-mark, .sg-radio:not(.is-disabled):hover .sg-radio-input:focus-visible + .sg-radio-mark { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-radio.is-invalid .sg-radio-input:not(:checked) ~ .sg-radio-mark { border-color: var(--status-bad); }
.sg-radio.is-invalid .sg-radio-input:checked ~ .sg-radio-mark { box-shadow: 0 0 0 2px var(--status-bad); }
.sg-radio.is-invalid .sg-radio-input:focus-visible + .sg-radio-mark, .sg-radio.is-invalid:not(.is-disabled):hover .sg-radio-input:focus-visible + .sg-radio-mark { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--status-bad); }
.sg-radio.is-disabled { opacity: var(--disabled); cursor: not-allowed; }

/* card variant: recipe F glass, outline turns ink when chosen, a tick sits top right (the mark itself, with the tick instead of the dot) */
.sg-radio--card { display: block; width: 100%; box-sizing: border-box; padding: var(--space-4); border-radius: var(--radius-md); font-size: 15px; line-height: 22px;
  background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4);
  transition: border-color var(--duration-quick) var(--ease-liquid), box-shadow var(--duration-quick) var(--ease-liquid); }
.sg-radio--card .sg-radio-input { inset: 0; width: 100%; height: 100%; }
.sg-radio--card .sg-radio-mark { position: absolute; top: 14px; right: 14px; margin: 0; background: var(--glass-strong); }
.sg-radio--card .sg-radio-dot { display: none; }
.sg-radio--card .sg-radio-body { display: grid; gap: 2px; padding-right: 28px; }
.sg-radio--card .sg-radio-icon { margin-bottom: var(--space-2); color: var(--ink); }
.sg-radio--card .sg-radio-title { font-weight: 500; }
.sg-radio--card .sg-radio-input:checked ~ .sg-radio-mark { background: var(--ink); border-color: var(--ink); color: var(--ink-inverse); }
.sg-radio-tick { position: absolute; inset: -1.5px; width: 20px; height: 20px; overflow: visible; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0; transition: stroke-dashoffset calc(var(--duration-quick) * 2 / 3) var(--ease-exit), opacity calc(var(--duration-quick) * 2 / 3) var(--ease-exit); }
.sg-radio-input:checked ~ .sg-radio-mark .sg-radio-tick { stroke-dashoffset: 0; opacity: 1; transition: stroke-dashoffset var(--duration-quick) var(--ease-liquid), opacity var(--duration-instant) linear; }
.sg-radio-ring { position: absolute; inset: -1px; border-radius: inherit; pointer-events: none; }
.sg-radio-input:focus-visible ~ .sg-radio-ring { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-radio--card:has(.sg-radio-input:checked) { border-color: var(--ink); box-shadow: inset 0 0 0 1px var(--ink), var(--shadow-glass); }
.sg-radio--card.is-invalid:not(:has(.sg-radio-input:checked)) { border-color: var(--status-bad); }
.sg-radio--card.is-invalid .sg-radio-input:focus-visible ~ .sg-radio-ring { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--status-bad); }
@media (hover: hover) {
  .sg-radio--card:not(.is-disabled):not(:has(.sg-radio-input:checked)):hover { border-color: var(--ink-2); }
  .sg-radio--card:not(.is-disabled):hover .sg-radio-mark { box-shadow: none; }
  .sg-radio--card:not(.is-disabled):hover .sg-radio-input:not(:checked) ~ .sg-radio-mark { border-color: var(--ink-2); }
}
.sg-radio--card:not(.is-disabled):active .sg-radio-mark { transform: scale(.92); box-shadow: none; }

@media (prefers-reduced-motion: reduce) {
  .sg-radio-mark { transition-property: background-color, border-color, box-shadow; }
  .sg-radio:not(.is-disabled):active .sg-radio-mark { transform: none; }
  .sg-radio-dot, .sg-radio-input:checked ~ .sg-radio-mark .sg-radio-dot { transform: scale(1); transition-property: opacity; opacity: 0; }
  .sg-radio-input:checked ~ .sg-radio-mark .sg-radio-dot { opacity: 1; }
  .sg-radio-tick, .sg-radio-input:checked ~ .sg-radio-mark .sg-radio-tick { stroke-dashoffset: 0; transition-property: opacity; }
}
@media (pointer: coarse) {
  .sg-radio:not(.sg-radio--card) { min-height: 44px; }
  .sg-radio.is-bare:not(.sg-radio--card) { min-height: 20px; }
  .sg-radio:not(.sg-radio--card) .sg-radio-input { top: 12px; }
  .sg-radio:not(.sg-radio--card) .sg-radio-mark { margin-top: 12px; }
  .sg-radio:not(.sg-radio--card) .sg-radio-text { padding-block: 11px; }
  .sg-radio--sm:not(.sg-radio--card) .sg-radio-text { padding-block: 12px; }
  .sg-radio.is-bare:not(.sg-radio--card) .sg-radio-input, .sg-radio.is-bare:not(.sg-radio--card) .sg-radio-mark { top: 0; margin-top: 0; }
  .sg-radio.is-bare:not(.sg-radio--card)::after { content: ""; position: absolute; inset: -12px; }
  .sg-radio-group:not(.sg-radio-group--card) { gap: 0; }
  .sg-radio-group--row:not(.sg-radio-group--card) { gap: 0 var(--space-6); }
}

/* ---------- Rating: five stars. Empty = 1.5px line-strong outline; set = ink fill + ink outline (Checkbox's "chosen = solid ink"); hover previews in ink at 40% ---------- */
.sg-rating { --sg-rt: 20px; --sg-rt-gap: 4px; display: inline-flex; align-items: center; gap: var(--space-2); max-width: 100%; vertical-align: middle; }
.sg-rating--sm { --sg-rt: 16px; --sg-rt-gap: 2px; }
.sg-rating--lg { --sg-rt: 28px; }
.sg-rating-stars { display: inline-flex; align-items: center; gap: var(--sg-rt-gap); border-radius: var(--radius-xs); }

/* a star: base outline + a hover-preview layer + a fill layer, stacked in one cell. The layers are clipped to the fraction (left to right) */
.sg-rating-star { position: relative; display: inline-grid; place-items: center; flex: none; width: var(--sg-rt); height: var(--sg-rt); border-radius: calc(var(--sg-rt) / 4); }
.sg-rating-star > * { grid-area: 1 / 1; }
.sg-rating .sg-icon { width: var(--sg-rt); height: var(--sg-rt); }
.sg-rating-base { stroke: var(--line-strong); fill: none; }
.sg-rating-layer { display: grid; pointer-events: none; }
.sg-rating-fill { clip-path: inset(0 calc(100% - var(--sg-rt-fill, 0%)) 0 0); }
.sg-rating-prev { clip-path: inset(0 calc(100% - var(--sg-rt-prev, 0%)) 0 0); }
.sg-rating-fill .sg-icon { fill: var(--ink); stroke: var(--ink); }
.sg-rating-prev .sg-icon { fill: color-mix(in srgb, var(--ink) 40%, transparent); stroke: color-mix(in srgb, var(--ink) 40%, transparent); }

/* the radios: invisible, laid over the star (over each half with allowHalf) so a press lands on the value under the pointer */
.sg-rating-input { position: absolute; top: 0; bottom: 0; left: 0; width: 100%; height: 100%; margin: 0; padding: 0; opacity: 0; cursor: pointer; z-index: 1; }
.sg-rating-input.is-l { width: 50%; }
.sg-rating-input.is-r { left: 50%; width: 50%; }
.sg-rating.is-interactive .sg-rating-star { touch-action: manipulation; -webkit-tap-highlight-color: transparent;
  transition: transform var(--duration-spring) var(--ease-spring-bouncy); }
/* pressed: .92, released: springs back past 1 and settles */
.sg-rating.is-interactive .sg-rating-star:active { transform: scale(.92); transition-duration: var(--duration-instant); transition-timing-function: var(--ease-liquid); }
.sg-rating-star.is-focus { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }

/* words and number: 13px ink-2. All level words share one cell, so the row does not change width as the level changes */
.sg-rating-text { display: inline-flex; align-items: baseline; gap: var(--space-2); font-size: 13px; line-height: 18px; color: var(--ink-2); white-space: nowrap; }
.sg-rating:lang(zh) .sg-rating-text, .sg-rating-text:lang(zh) { line-height: 20px; }
.sg-rating-value { min-width: 2.2ch; font-variant-numeric: tabular-nums; }
.sg-rating-value.is-empty { color: var(--ink-3); }
.sg-rating-label { display: inline-grid; }
.sg-rating-word { grid-area: 1 / 1; opacity: 0; transition: opacity var(--duration-quick) var(--ease-liquid); }
.sg-rating-word.is-on { opacity: 1; }

.sg-rating.is-disabled { opacity: var(--disabled); }
.sg-rating.is-disabled .sg-rating-input { cursor: not-allowed; }
.sg-rating.is-invalid .sg-rating-base { stroke: var(--status-bad); }

@media (forced-colors: active) {
  .sg-rating-base { stroke: CanvasText; }
  .sg-rating-fill .sg-icon { fill: Highlight; stroke: Highlight; }
  .sg-rating-prev .sg-icon { fill: GrayText; stroke: GrayText; }
}
@media (prefers-reduced-motion: reduce) {
  /* the star does not shrink or bounce; the fill still changes at once */
  .sg-rating.is-interactive .sg-rating-star { transition: none; }
  .sg-rating.is-interactive .sg-rating-star:active { transform: none; }
  .sg-rating-word { transition: none; }
}
@media (pointer: coarse) {
  /* under a finger every star is a 44 x 44 cell (the stars spread out; a read-only score stays compact) */
  .sg-rating.is-interactive .sg-rating-stars { gap: 0; }
  .sg-rating.is-interactive .sg-rating-star { width: 44px; height: 44px; border-radius: var(--radius-xs); }
  .sg-rating.is-interactive .sg-rating-text { margin-left: var(--space-1); }
}

/* ---------- Result: the same column as EmptyState (visual, title, words, actions), left-aligned on the area's left edge ---------- */
.sg-result { min-width: 0; color: var(--ink); }
.sg-result-col { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }
/* a page: the column is centred in the viewport, at most 480 wide, text inside stays left-aligned */
.sg-result--page .sg-result-col { box-sizing: border-box; max-width: 480px; margin-inline: auto; padding: var(--space-12) var(--space-4); }
.sg-result--card .sg-result-col { max-width: 46ch; }

/* the mark: a 56px glass disc with a 28px icon in the status colour; 404 / 500 have no disc, the code itself is the visual */
.sg-result-visual { flex: none; display: grid; place-items: center; box-sizing: border-box; width: 56px; height: 56px; margin-bottom: var(--space-4); border-radius: 50%;
  background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass); color: var(--ink-2);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-result-visual .sg-icon { width: 28px; height: 28px; }
.sg-result-visual.is-good { color: var(--status-good); }
.sg-result-visual.is-bad { color: var(--status-bad); }
.sg-result-visual.is-warn { color: var(--status-warn); }
.sg-result-code { width: auto; height: auto; margin-bottom: var(--space-3); border: 0; border-radius: 0; background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; color: var(--ink); place-items: start; }
.sg-result-code .sg-dot { color: var(--ink); }

.sg-result-title { margin: 0; color: var(--ink); overflow-wrap: anywhere; outline: none; }
.sg-result-desc { margin: var(--space-2) 0 0; color: var(--ink-2); }
.sg-result-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-top: var(--space-6); }
.sg-result--card .sg-result-actions { gap: var(--space-2); margin-top: var(--space-4); }
.sg-result-extra { width: 100%; margin-top: var(--space-4); }

/* success and failure draw their strokes once, when the status changes (path lengths are measured into --sg-len) */
.sg-result-visual.is-draw .sg-icon path { stroke-dasharray: var(--sg-len, 60); stroke-dashoffset: var(--sg-len, 60);
  animation: sg-result-draw var(--duration-smooth) var(--ease-liquid) calc(var(--sg-i, 0) * 90ms) forwards; }
@keyframes sg-result-draw { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  .sg-result-visual.is-draw .sg-icon path { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
}
@media (pointer: coarse) {
  /* a status page has no small targets of its own; the buttons in `actions` bring their own hit areas */
}

/* ---------- ScrollArea: the wrapper holds layout, size limits and the focus ring; the viewport scrolls and carries the fade mask ---------- */
.sg-scrollarea { position: relative; display: flex; flex-direction: column; min-width: 0; min-height: 0; border-radius: var(--radius-xs); }
.sg-scrollarea.is-focus { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-scrollarea-viewport { flex: 1 1 auto; min-width: 0; min-height: 0; box-sizing: border-box; overscroll-behavior: contain; scroll-behavior: auto; border-radius: inherit; outline: none; }
.sg-scrollarea--vertical > .sg-scrollarea-viewport { overflow-x: hidden; overflow-y: auto; }
.sg-scrollarea--horizontal > .sg-scrollarea-viewport { overflow-x: auto; overflow-y: hidden; }
.sg-scrollarea--both > .sg-scrollarea-viewport { overflow: auto; }
/* scrollbar: the system's own thin bar (the --scrollbar token); "hidden" removes it, scrolling still works */
.sg-scrollarea-viewport.is-bare { scrollbar-width: none; }
.sg-scrollarea-viewport.is-bare::-webkit-scrollbar { display: none; }

/* fade: a mask, not a coat of background colour, so a glass card behind stays glass. Depths (0..24px) are written by script from the scroll position */
.sg-scrollarea-viewport.is-fade { --sg-fade-t: 0px; --sg-fade-b: 0px; --sg-fade-l: 0px; --sg-fade-r: 0px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, black var(--sg-fade-t), black calc(100% - var(--sg-fade-b)), transparent 100%), linear-gradient(to right, transparent 0, black var(--sg-fade-l), black calc(100% - var(--sg-fade-r)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, black var(--sg-fade-t), black calc(100% - var(--sg-fade-b)), transparent 100%), linear-gradient(to right, transparent 0, black var(--sg-fade-l), black calc(100% - var(--sg-fade-r)), transparent 100%);
  -webkit-mask-composite: source-in; mask-composite: intersect; }

/* arrows (horizontal only): an xs glass IconButton at each edge, hidden at the ends */
.sg-scrollarea-arrow { position: absolute; top: 50%; z-index: 2; margin-top: calc(var(--control-xs) / -2); background: var(--glass-overlay);
  transition: opacity var(--duration-quick) var(--ease-liquid), background-color var(--duration-instant), transform var(--duration-quick) var(--ease-liquid); }
.sg-scrollarea-arrow.is-start { left: 4px; }
.sg-scrollarea-arrow.is-end { right: 4px; }
.sg-scrollarea-arrow:not([disabled]):hover { background: var(--glass-overlay); box-shadow: var(--shadow-lift); }
.sg-scrollarea-arrow.is-off { opacity: 0; pointer-events: none; }
.sg-scrollarea-arrow .sg-icon { width: 14px; height: 14px; }

@media (prefers-reduced-motion: reduce) {
  /* arrows only fade, they do not scale on press; the script scrolls by a jump instead of gliding */
  .sg-scrollarea-arrow { transition-property: opacity, background-color; }
  .sg-scrollarea-arrow:active { transform: none; }
}
@media (pointer: coarse) {
  /* a touch screen scrolls by swiping and the fade shows there is more: no 24px arrows to tap */
  .sg-scrollarea-arrow { display: none; }
}

/* ---------- SegmentedControl: glass track (44 / 32 high, 3px inside), solid thumb with shadow-lift, 14 / 500 text ---------- */
.sg-seg { position: relative; display: inline-flex; align-items: stretch; box-sizing: border-box; width: fit-content; max-width: 100%; height: var(--control-md); padding: 3px; vertical-align: middle;
  border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--glass);
  -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md)); }
.sg-seg--sm { height: var(--control-sm); }
.sg-seg--block { display: flex; width: 100%; }
.sg-seg.is-invalid { border-color: var(--status-bad); }
.sg-seg.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
/* a Field around it (hint or error): the track keeps its own width */
.sg-field > .sg-seg { align-self: flex-start; }
.sg-field > .sg-seg--block { align-self: stretch; }

/* thumb: only transform and width move; the style attribute switches the glide off for the first paint and for resizes */
.sg-seg-thumb { position: absolute; z-index: 0; top: 3px; left: 0; height: calc(100% - 6px); border-radius: var(--radius-pill); background: var(--solid); box-shadow: var(--shadow-lift); pointer-events: none;
  transition: transform var(--duration-spring) var(--ease-spring-soft), width var(--duration-spring) var(--ease-spring-soft), scale var(--duration-quick) var(--ease-liquid); }
.sg-seg:has(.sg-seg-opt.is-on:active:not(.is-disabled)) .sg-seg-thumb { scale: .96; }

/* option: a label over a real radio (invisible, covers the whole segment) */
.sg-seg-opt { position: relative; z-index: 1; flex: 0 0 auto; display: flex; min-width: 0; border-radius: var(--radius-pill); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.sg-seg--block .sg-seg-opt { flex: 1 1 0; }
.sg-seg-input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: inherit; }
.sg-seg-text { display: flex; flex: 1; align-items: center; justify-content: center; min-width: 0; padding: 0 var(--space-4); border-radius: var(--radius-pill);
  font-size: 14px; font-weight: 500; line-height: 1; white-space: nowrap; color: var(--ink-2);
  transition: color var(--duration-quick) var(--ease-liquid), background-color var(--duration-instant), scale var(--duration-quick) var(--ease-liquid); }
.sg-seg--sm .sg-seg-text { padding: 0 var(--space-3); font-size: 13px; }
.sg-seg-opt.is-icon .sg-seg-text { padding: 0 14px; }
.sg-seg--sm .sg-seg-opt.is-icon .sg-seg-text { padding: 0 8px; }
.sg-seg-opt.is-on .sg-seg-text { color: var(--ink); }
@media (hover: hover) {
  .sg-seg-opt:not(.is-on):not(.is-disabled):hover .sg-seg-text { background: var(--state-hover); color: var(--ink); }
}
.sg-seg-opt:not(.is-disabled):active .sg-seg-text { scale: .96; }
.sg-seg-opt.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
/* focus: the double ring sits on the current segment */
.sg-seg-input:focus-visible + .sg-seg-text { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-seg-input:disabled { cursor: not-allowed; }

/* the chosen text sits on the solid thumb, which is light in both themes: dark text on it, as PillTabs does */
[data-theme="dark"] .sg-seg-opt.is-on .sg-seg-text { color: var(--ink-inverse); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sg-seg-opt.is-on .sg-seg-text { color: var(--ink-inverse); }
}
@media (forced-colors: active) {
  .sg-seg-thumb { background: Highlight; forced-color-adjust: none; }
  .sg-seg-opt.is-on .sg-seg-text { color: HighlightText; forced-color-adjust: none; }
}

@media (prefers-reduced-motion: reduce) {
  /* the thumb jumps, nothing scales */
  .sg-seg-thumb { transition: none !important; }
  .sg-seg:has(.sg-seg-opt.is-on:active) .sg-seg-thumb, .sg-seg-opt:not(.is-disabled):active .sg-seg-text { scale: none; }
}
@media (pointer: coarse) {
  /* the 32px size gets a 44px target: each option's input reaches 6px above and below the track; a short label or an icon alone is widened to 44 */
  .sg-seg--sm .sg-seg-input { top: -10px; bottom: -10px; height: auto; }
  .sg-seg-opt { min-width: 44px; }
}

/* ---------- Select: recipe-A shell whose face is a button (value + chevron); the list is the shared recipe-D / recipe-E panel ---------- */
/* min-width: 0 lets the shell shrink to its container, so a long value can fall back to its ellipsis */
.sg-sel.sg-field-box { padding: 0; min-width: 0; cursor: pointer; }
.sg-sel.is-disabled { cursor: not-allowed; }
.sg-sel.is-open:not(.is-invalid) { border-color: var(--ink); }
/* the shell's focus rings belong to the keyboard (:focus-visible), like Button's: a press with the mouse leaves the border change (open) but no rings.
   The shared .sg-field-box:focus-within rule is written for text boxes, which show their rings for every kind of focus. */
.sg-sel.sg-field-box:focus-within:not(:has(:focus-visible)) { box-shadow: none; }
.sg-field.is-error .sg-sel.sg-field-box:focus-within:not(:has(:focus-visible)) { box-shadow: none; }
.sg-sel-trigger { flex: 1; min-width: 0; height: 100%; display: flex; align-items: center; gap: var(--space-2); box-sizing: border-box; margin: 0; padding: 0 0 0 14px; border: 0; border-radius: inherit;
  background: none; color: inherit; font: inherit; font-size: 15px; text-align: start; cursor: inherit; outline: none; }
.sg-sel.sg-field-box--sm .sg-sel-trigger { padding-left: 12px; font-size: 14px; }
.sg-sel-icon { width: 18px; height: 18px; flex: none; color: var(--ink-2); }
.sg-sel-icon.is-option { width: 16px; height: 16px; }
.sg-sel-value { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-sel-value.is-placeholder { color: var(--ink-2); }
.sg-sel-chev { flex: none; align-self: stretch; display: grid; place-items: center; padding-right: 14px; color: var(--ink-2); cursor: inherit; }
.sg-sel.sg-field-box--sm .sg-sel-chev { padding-right: 12px; }
.sg-sel-chev .sg-icon { width: 16px; height: 16px; transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-sel.is-open .sg-sel-chev .sg-icon { transform: rotate(180deg); }
/* the 24px clear button keeps the same margin to the box edge above and below (the box is 1px bordered) */
.sg-sel-clear { flex: none; }
/* the line that says there is nothing to pick is a message, not a greyed-out option: no extra dimming on top of ink-2 */
.sg-menu-item.sg-sel-none[aria-disabled="true"] { opacity: 1; cursor: default; }
.sg-sel-none .sg-menu-title { color: var(--ink-2); }

@media (prefers-reduced-motion: reduce) {
  /* the arrow still turns over to show the list is open, it just does not turn slowly */
  .sg-sel-chev .sg-icon { transition: none; }
}
@media (pointer: coarse) {
  /* the 24px clear button reaches 44px through IconButton's own touch rule; in a 32px shell it sits above the shell's 6px strips */
  .sg-sel-clear { position: relative; z-index: 1; }
  .sg-sel .sg-sel-chev { padding-left: 6px; }
}

/* ---------- SendCodeButton: a Button whose width never changes; waiting states are dimmer words, not a dimmed button ---------- */
.sg-btn.sg-sendcode > .sg-busy { display: none; }   /* the three dots live inside the stack, so the width does not move */
.sg-sendcode-stack { display: inline-grid; justify-items: center; }
.sg-sendcode-stack > * { grid-area: 1 / 1; }
.sg-sendcode-live { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); max-width: 100%; font-variant-numeric: tabular-nums; }
.sg-sendcode-ghost { visibility: hidden; height: 0; overflow: hidden; pointer-events: none; font-variant-numeric: tabular-nums; }
/* cooling, locked, sending: still readable (ink-2, no opacity), still focusable, nothing lifts or presses */
.sg-btn.sg-sendcode.is-wait, .sg-btn.sg-sendcode.is-sending { color: var(--ink-2); cursor: default; }
.sg-btn.sg-sendcode.is-wait:not([disabled]):hover:not(:focus-visible), .sg-btn.sg-sendcode.is-sending:not([disabled]):hover:not(:focus-visible) { box-shadow: var(--shadow-glass); }
.sg-btn.sg-sendcode--ghost.is-wait:not([disabled]):hover:not(:focus-visible), .sg-btn.sg-sendcode--ghost.is-sending:not([disabled]):hover:not(:focus-visible) { box-shadow: none; }
.sg-btn.sg-sendcode.is-wait:active, .sg-btn.sg-sendcode.is-sending:active { transform: none; }
/* text: no fill, no frame; a soft pill on hover. It sits on its own line under a PinInput. */
.sg-btn.sg-sendcode--text { background: transparent; border-color: transparent; box-shadow: none; padding: 0 12px; color: var(--ink); }
.sg-btn.sg-sendcode--text:not([disabled]):hover:not(:focus-visible) { box-shadow: none; }
.sg-btn.sg-sendcode--text:not([disabled]):not(.is-wait):not(.is-sending):hover { background: var(--state-hover); }
.sg-btn.sg-sendcode--text.is-wait, .sg-btn.sg-sendcode--text.is-sending { color: var(--ink-2); }
.sg-btn.sg-sendcode--text:active:not(.is-wait):not(.is-sending) { background: var(--state-pressed); }

@media (prefers-reduced-motion: reduce) {
  /* nothing here moves: the words just change */
  .sg-btn.sg-sendcode:active { transform: none; }
}
@media (pointer: coarse) {
  /* sm buttons already reach 44px through Button's own rule; the text variant at md is 44 high */
}

/* ---------- Sidebar: 256 px glass panel (or a mist edge) with grouped rows, one level of nesting, a sliding solid pill on the current row, and a 72 px icon rail when collapsed ---------- */
@property --sg-sb-w { syntax: "<length>"; inherits: false; initial-value: 256px; }

.sg-sidebar { position: relative; box-sizing: border-box; flex: none; display: flex; flex-direction: column; width: var(--sg-sb-w); min-width: 0; overflow: hidden; color: var(--ink); font-size: 15px; line-height: 22px;
  padding: var(--space-3) 14px; --sg-badge-ring: var(--mist-100);
  transition: --sg-sb-w var(--duration-smooth) var(--ease-spring-soft); }
/* glass: floats 12px from the window's top, bottom and left edge */
.sg-sidebar--glass { height: calc(100% - var(--space-6)); margin: var(--space-3) 0 var(--space-3) var(--space-3); border-radius: var(--radius-lg);
  background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4); }
/* mist: flat against the edge, a hairline on its right (a docs site) */
.sg-sidebar--mist { height: 100%; padding-left: 15px; background: var(--mist-100); border-right: 1px solid var(--line); }
/* hidden off-canvas: gone (no animation; a rail that slides away is the icon collapse's job) */
.sg-sidebar.is-off { display: none; }
/* inside an AppShell's drawer: the drawer is the glass, the sidebar is just its content */
.sg-sidebar.is-drawer { flex: 1 0 auto; width: 100%; height: auto; margin: 0; border: 0; border-radius: 0; background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; transition: none; --sg-badge-ring: var(--mist-100); }

.sg-sidebar-top { flex: none; display: flex; align-items: center; gap: var(--space-2); padding-bottom: var(--space-3); }
.sg-sidebar-header { flex: 1 1 auto; min-width: 0; }
.sg-sidebar-toggle { flex: none; margin-inline-start: auto; }   /* with no header slot the button still sits at the right */
.sg-sidebar.is-rail .sg-sidebar-toggle { margin-inline-start: 0; }
.sg-sidebar.is-rail .sg-sidebar-top { flex-direction: column; }
.sg-sidebar.is-rail .sg-sidebar-header { flex: none; display: flex; width: 44px; height: 44px; overflow: hidden; }

/* in the drawer the drawer's own body scrolls: the list takes its natural height instead of the leftover space */
.sg-sidebar.is-drawer .sg-sidebar-scroll { flex: 1 0 auto; }
/* the scrolling middle: 8px of room each side so rows and their focus rings are not cut at the edge */
.sg-sidebar-scroll { flex: 1 1 0; min-height: 0; margin-inline: -8px; border-radius: 0; }
.sg-sidebar-nav { position: relative; isolation: isolate; padding: 4px 8px; }

.sg-sidebar-group + .sg-sidebar-group { margin-top: var(--space-4); }
.sg-sidebar-group-title { margin: 0 0 var(--space-1); padding: 0 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; line-height: 20px; font-weight: 400; letter-spacing: normal; color: var(--ink-2); }
.sg-sidebar-gdiv { display: none; }
.sg-sidebar-list, .sg-sidebar-sublist { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.sg-sidebar-sublist { padding-top: 2px; }
.sg-sidebar-li { position: relative; }
.sg-sidebar-row { position: relative; display: flex; align-items: center; }
.sg-sidebar-row .sg-badge-wrap { display: flex; flex: 1 1 auto; min-width: 0; }

/* the row: 40 high, radius-sm; the icon column sits so its centre is 36px from the panel's edge in both widths (the rail's icons do not move when the panel narrows) */
.sg-sidebar-main { position: relative; z-index: 1; box-sizing: border-box; display: flex; align-items: center; gap: var(--space-3); flex: 1 1 auto; width: 100%; min-width: 0; height: var(--row-sm); margin: 0; padding: 0 12px;
  border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--ink-2); font: inherit; font-size: 15px; line-height: 22px; font-weight: 400; text-align: start; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--duration-instant) var(--ease-liquid), color var(--duration-base) var(--ease-liquid); }
.sg-sidebar-main:not(.is-current):not(.is-disabled):hover { background: var(--state-hover); color: var(--ink); }
.sg-sidebar-main:not(.is-current):not(.is-disabled):active { background: var(--state-pressed); }
.sg-sidebar-main.is-ancestor { color: var(--ink); }
/* on the solid pill: ink on white in the light theme, ink-inverse on the bright pill in the dark one */
.sg-sidebar-main.is-current { color: var(--ink); color: light-dark(var(--ink), var(--ink-inverse)); font-weight: 500; }
.sg-sidebar-main.is-disabled, .sg-sidebar-main:disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-sidebar-main.is-child { padding-left: 42px; }
.sg-sidebar-icon { width: 18px; height: 18px; flex: none; color: inherit; }
.sg-sidebar-initial { display: none; }
.sg-sidebar-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-sidebar-end { margin-inline-start: auto; flex: none; display: inline-flex; align-items: center; gap: var(--space-2); transition: opacity var(--duration-quick) var(--ease-liquid); }
.sg-sidebar-count { font-family: var(--font-mono); font-size: 12px; line-height: 16px; font-weight: 400; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-sidebar-main.is-current .sg-sidebar-count { color: inherit; }
.sg-sidebar-chev { width: 16px; height: 16px; flex: none; margin-inline-start: auto; color: var(--ink-3); transition: transform calc(var(--duration-smooth) * 2 / 3) var(--ease-exit); }
.sg-sidebar-end + .sg-sidebar-chev { margin-inline-start: 0; }
.sg-sidebar-main.is-current .sg-sidebar-chev { color: inherit; }
.sg-sidebar-li.is-open > .sg-sidebar-row .sg-sidebar-chev { transform: rotate(90deg); transition: transform var(--duration-smooth) var(--ease-spring-soft); }

/* the secondary action of a row (an xs ghost IconButton, a menu trigger): shown on hover and while the row has focus, always in the tab order */
.sg-sidebar-action { position: absolute; z-index: 2; top: 50%; right: 6px; transform: translateY(-50%); display: inline-flex; align-items: center; opacity: 0; pointer-events: none; transition: opacity var(--duration-quick) var(--ease-liquid); }
.sg-sidebar-row.is-parent .sg-sidebar-action { right: 30px; }
.sg-sidebar-row:hover .sg-sidebar-action, .sg-sidebar-row:focus-within .sg-sidebar-action { opacity: 1; pointer-events: auto; }
.sg-sidebar-row.has-action:hover .sg-sidebar-end, .sg-sidebar-row.has-action:focus-within .sg-sidebar-end { opacity: 0; }

/* nested rows open with grid-template-rows 0fr → 1fr; closed they leave the tab order once the exit has finished; the clip has room for the focus ring */
.sg-sidebar-sub { display: grid; grid-template-rows: 0fr; visibility: hidden;
  transition: grid-template-rows calc(var(--duration-smooth) * 2 / 3) var(--ease-exit), visibility 0s linear calc(var(--duration-smooth) * 2 / 3); }
.sg-sidebar-li.is-open > .sg-sidebar-sub { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows var(--duration-smooth) var(--ease-spring-soft), visibility 0s; }
.sg-sidebar-clip { min-height: 0; overflow: hidden; margin: -4px -6px; padding: 4px 6px; }

/* the sliding pill (recipe C) */
.sg-sidebar-ind { position: absolute; z-index: 0; top: 0; left: 0; border-radius: var(--radius-sm); background: var(--solid); box-shadow: var(--shadow-lift); pointer-events: none;
  transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-sidebar-ind.is-still { transition: none; }

.sg-sidebar-footer { flex: none; min-width: 0; margin-top: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--line); }
.sg-sidebar.is-rail .sg-sidebar-footer { display: flex; width: 44px; margin-inline: auto; overflow: hidden; border-top-color: transparent; }

/* collapsed to the rail: 72px (border included), 44px round icon buttons like NavRail; names come from the Tooltip, nested rows from the flyout, group titles become a short hairline */
.sg-sidebar.is-rail { padding-inline: 13px; }
.sg-sidebar--mist.is-rail { padding-left: 14px; }
.sg-sidebar.is-rail .sg-sidebar-list { align-items: center; gap: var(--space-2); }
.sg-sidebar.is-rail .sg-sidebar-group + .sg-sidebar-group { margin-top: var(--space-3); }
.sg-sidebar.is-rail .sg-sidebar-group-title, .sg-sidebar.is-rail .sg-sidebar-label, .sg-sidebar.is-rail .sg-sidebar-end, .sg-sidebar.is-rail .sg-sidebar-chev,
.sg-sidebar.is-rail .sg-sidebar-action, .sg-sidebar.is-rail .sg-sidebar-sub { display: none; }
.sg-sidebar.is-rail .sg-sidebar-gdiv { display: block; width: 24px; margin: 0 auto var(--space-3); }
.sg-sidebar.is-rail .sg-sidebar-row { width: 44px; }
.sg-sidebar.is-rail .sg-sidebar-row .sg-badge-wrap { flex: none; width: 44px; }
.sg-sidebar.is-rail .sg-sidebar-main { flex: none; width: 44px; height: 44px; padding: 0; justify-content: center; border-radius: var(--radius-pill); }
.sg-sidebar.is-rail .sg-sidebar-icon { width: 20px; height: 20px; }
.sg-sidebar.is-rail .sg-sidebar-initial { display: grid; place-items: center; width: 22px; height: 22px; font-size: 16px; line-height: 22px; font-weight: 500; }
.sg-sidebar.is-rail .sg-sidebar-ind { border-radius: var(--radius-pill); }

/* the flyout of a nested item on the rail: a Popover-shaped panel (recipe D, radius-md) with the links */
.sg-overlay.sg-sidebar-fly { padding: var(--space-2); min-width: 200px; max-width: min(320px, var(--sg-avail-w, 100vw)); }
.sg-sidebar-fly-title { padding: 6px 12px 4px; font-size: 12px; line-height: 16px; font-weight: 400; color: var(--ink-2); }
.sg-sidebar-fly-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.sg-sidebar-fly-item { box-sizing: border-box; display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: 36px; margin: 0; padding: 6px 12px; border: 0; border-radius: var(--radius-xs); background: transparent;
  color: var(--ink); font: inherit; font-size: 15px; line-height: 20px; text-align: start; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-instant) var(--ease-liquid); }
.sg-sidebar-fly-item:hover { background: var(--state-hover); }
.sg-sidebar-fly-item:active { background: var(--state-pressed); }
.sg-sidebar-fly-item:disabled { opacity: var(--disabled); cursor: not-allowed; }
/* on glass-overlay a solid pill would not show: the current row takes the selected wash and a check */
.sg-sidebar-fly-item.is-current { font-weight: 500; background: var(--state-selected); }
.sg-sidebar-fly-check { width: 16px; height: 16px; flex: none; margin-inline-start: auto; visibility: hidden; }
.sg-sidebar-fly-item.is-current .sg-sidebar-fly-check { visibility: visible; }

@media (hover: none) {
  /* no hover on a touch screen: a row's action is simply there, in place of its count */
  .sg-sidebar-action { opacity: 1; pointer-events: auto; }
  .sg-sidebar-row.has-action .sg-sidebar-end { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  /* width changes at once, the pill jumps, groups open without growing; colours and opacity still change */
  .sg-sidebar { transition: none; }
  .sg-sidebar-ind { transition: none; }
  .sg-sidebar-sub, .sg-sidebar-li.is-open > .sg-sidebar-sub { transition: visibility 0s; }
  .sg-sidebar-chev, .sg-sidebar-li.is-open > .sg-sidebar-row .sg-sidebar-chev { transition: none; }
}
@media (pointer: coarse) {
  /* rows are 44px, the flyout's rows too; the xs action buttons get their 44px reach from core */
  .sg-sidebar:not(.is-rail) .sg-sidebar-main { min-height: 44px; }
  .sg-sidebar-fly-item { min-height: 44px; }
}

/* ---------- SiteHeader: 64 px (56 narrow) bar; hover pill between items; one shared panel viewport that morphs between items ---------- */
@property --sg-sh-x { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --sg-sh-w { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --sg-sh-h { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --sg-sh-hw { syntax: "<length>"; inherits: false; initial-value: 0px; }

.sg-siteheader { --sg-page-px: var(--space-4); position: relative; isolation: isolate; box-sizing: border-box; width: 100%; color: var(--ink); font-size: 15px; line-height: 22px; }
@media (min-width: 640px) { .sg-siteheader { --sg-page-px: var(--space-6); } }
@media (min-width: 1024px) { .sg-siteheader { --sg-page-px: var(--space-8); } }
@media (min-width: 1440px) { .sg-siteheader { --sg-page-px: var(--space-12); } }
.sg-siteheader.is-sticky { position: sticky; top: 0; z-index: var(--z-sticky); }
/* the glass layer: faded in once the page has scrolled (opacity is the one thing animated) */
.sg-siteheader::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: 0; background: var(--glass-overlay); border-bottom: 1px solid var(--line);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4); transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-siteheader[data-stuck]::before { opacity: 1; }
.sg-siteheader.in-shell::before { display: none; }

.sg-siteheader-in { box-sizing: border-box; display: flex; align-items: center; gap: var(--space-6); height: 64px; max-width: calc(var(--sg-content-max, 1200px) + 2 * var(--sg-page-px)); margin-inline: auto; padding-inline: var(--sg-page-px); }
.sg-siteheader.is-narrow .sg-siteheader-in { height: 56px; gap: var(--space-2); }
.sg-siteheader-brand { flex: none; display: flex; align-items: center; min-width: 0; }
.sg-siteheader-end { margin-inline-start: auto; flex: none; display: flex; align-items: center; gap: var(--space-1); }
.sg-siteheader-actions { margin-inline-start: auto; flex: none; display: flex; align-items: center; gap: var(--space-2); }

/* the "skip to content" link: out of sight until it takes focus, then an ink button in the top-left corner */
.sg-siteheader-skip:not(:focus) { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.sg-siteheader-skip:focus { position: fixed; top: var(--space-2); left: var(--space-2); z-index: calc(var(--z-sticky) + 1); }

/* the main links */
.sg-siteheader-nav { position: relative; flex: 1 1 auto; min-width: 0; }
.sg-siteheader-list { list-style: none; margin: 0; padding: 0; display: flex; align-items: center; gap: var(--space-1); }
.sg-siteheader-li { display: flex; }
.sg-siteheader-item { position: relative; z-index: 1; box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--space-1); height: 40px; margin: 0; padding: 0 12px; border: 0; border-radius: var(--radius-pill); background: transparent;
  color: var(--ink-2); font: inherit; font-size: 15px; line-height: 22px; font-weight: 500; text-decoration: none; white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: color var(--duration-quick) var(--ease-liquid); }
.sg-siteheader-item:hover, .sg-siteheader-item.is-open, .sg-siteheader-item.is-current { color: var(--ink); }
/* the current page: ink text and a 2px ink bar under the words */
.sg-siteheader-item.is-current::after { content: ""; position: absolute; left: 50%; bottom: 3px; width: 16px; height: 2px; margin-left: -8px; border-radius: var(--radius-pill); background: var(--ink); }
.sg-siteheader-chev { width: 14px; height: 14px; flex: none; transition: transform calc(var(--duration-base) * 2 / 3) var(--ease-exit); }
.sg-siteheader-item.is-open .sg-siteheader-chev { transform: rotate(180deg); transition: transform var(--duration-base) var(--ease-spring-soft); }
/* the hover pill: one block behind the items; it slides between them, and fades in place when the pointer leaves */
.sg-siteheader-hover { position: absolute; z-index: 0; top: 0; left: 0; width: var(--sg-sh-hw); border-radius: var(--radius-pill); background: var(--state-hover); opacity: 0; pointer-events: none;
  transition: transform var(--duration-base) var(--ease-liquid), --sg-sh-hw var(--duration-base) var(--ease-liquid), opacity var(--duration-base) var(--ease-liquid); }
.sg-siteheader-hover.is-on { opacity: 1; }
.sg-siteheader-hover.is-still { transition: opacity var(--duration-base) var(--ease-liquid); }

/* the shared panel viewport: under the header, recipe D at radius-md; its size and place are custom properties, so moving between items morphs it */
.sg-siteheader-viewport { position: absolute; z-index: 1; top: calc(100% + var(--space-2)); left: 0; box-sizing: border-box; width: var(--sg-sh-w); height: var(--sg-sh-h); translate: var(--sg-sh-x) 0; overflow: hidden;
  border-radius: var(--radius-md); background: var(--glass-overlay); border: 1px solid var(--line); box-shadow: var(--shadow-float); transform-origin: 50% 0; --sg-ov-dx: 0px; --sg-ov-dy: -4px;
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4);
  transition: --sg-sh-w var(--duration-smooth) var(--ease-spring-soft), --sg-sh-h var(--duration-smooth) var(--ease-spring-soft), --sg-sh-x var(--duration-smooth) var(--ease-spring-soft); }
.sg-siteheader-viewport.is-still { transition: none; }
.sg-siteheader-viewport[data-state="open"] { animation: sg-ov-in var(--duration-quick) var(--ease-liquid) both; }
.sg-siteheader-viewport[data-state="closed"] { animation: sg-ov-out calc(var(--duration-quick) * 2 / 3) var(--ease-exit) both; pointer-events: none; }
/* the pointer's way from an item to its panel crosses 8px of nothing: a bridge keeps it inside */
.sg-siteheader-viewport::before { content: ""; position: absolute; left: 0; right: 0; top: -9px; height: 9px; }
/* contents are laid on top of each other from the top-left corner; the viewport clips them, so the slide never shows outside */
.sg-siteheader-content { position: absolute; top: 0; left: 0; box-sizing: border-box; display: flex; align-items: flex-start; gap: var(--space-3); width: max-content; max-width: min(960px, calc(100vw - 32px)); padding: var(--space-3); }
.sg-siteheader-content[data-dir] { animation: sg-sh-in var(--duration-base) var(--ease-liquid) both; }
.sg-siteheader-content.is-exit { animation: sg-sh-out calc(var(--duration-base) * 2 / 3) var(--ease-exit) both; pointer-events: none; }
.sg-siteheader-content[data-dir="1"] { --sg-sh-dir: 1; }
.sg-siteheader-content[data-dir="-1"] { --sg-sh-dir: -1; }
@keyframes sg-sh-in { from { opacity: 0; transform: translateX(calc(var(--sg-sh-dir, 1) * 8px)); } }
@keyframes sg-sh-out { to { opacity: 0; transform: translateX(calc(var(--sg-sh-dir, 1) * -8px)); } }
.sg-siteheader-col { width: 240px; min-width: 0; }
.sg-siteheader-col-title { margin: 0; padding: 6px 12px 4px; font-size: 12px; line-height: 16px; font-weight: 400; color: var(--ink-2); }
.sg-siteheader-links { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.sg-siteheader-link { box-sizing: border-box; display: flex; align-items: flex-start; gap: var(--space-3); padding: 8px 12px; border-radius: var(--radius-xs); color: var(--ink); text-decoration: none; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--duration-instant) var(--ease-liquid); }
.sg-siteheader-link:hover { background: var(--state-hover); }
.sg-siteheader-link:active { background: var(--state-pressed); }
/* on glass-overlay a solid fill would not show: the current link takes the selected wash */
.sg-siteheader-link.is-current { background: var(--state-selected); }
.sg-siteheader-link-icon { width: 16px; height: 16px; flex: none; margin-top: 3px; color: var(--ink-2); }
.sg-siteheader-link-text { min-width: 0; display: grid; }
.sg-siteheader-link-title { font-size: 15px; line-height: 22px; font-weight: 500; }
.sg-siteheader-link-desc { font-size: 13px; line-height: 18px; font-weight: 400; color: var(--ink-2); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.sg-siteheader-featured { width: 240px; flex: none; }

/* narrow: the Drawer's list. Link rows are 52px like Accordion's title rows, with a hairline between every two */
.sg-overlay.sg-siteheader-drawer .sg-modal-title { display: flex; align-items: center; min-height: 32px; }
.sg-siteheader-m { display: block; }
.sg-siteheader-m > * + * { border-top: 1px solid var(--line); }
.sg-siteheader-m-row { box-sizing: border-box; display: flex; align-items: center; min-height: var(--row-md); width: calc(100% + 24px); margin-inline: -12px; padding: 12px; border-radius: var(--radius-xs); color: var(--ink); text-decoration: none; font-size: 15px; line-height: 22px; font-weight: 500; transition: background-color var(--duration-instant) var(--ease-liquid); }
.sg-siteheader-m-row:hover { background: var(--state-hover); }
.sg-siteheader-m-row.is-current { background: var(--state-selected); }
.sg-siteheader-m-sec .sg-accordion-body { padding-bottom: var(--space-2); }
.sg-siteheader-m-links { display: grid; gap: var(--space-2); }
.sg-siteheader-m-links .sg-siteheader-col { width: auto; }
.sg-siteheader-m-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); width: 100%; justify-content: flex-end; }

@media (prefers-reduced-motion: reduce) {
  /* the panel appears and goes with a fade, changes size and place at once, and the content swaps without sliding; the hover pill jumps and fades */
  .sg-siteheader-viewport { transition: none; }
  .sg-siteheader-viewport[data-state="open"] { animation-name: sg-ov-fade; }
  .sg-siteheader-viewport[data-state="closed"] { animation-name: sg-ov-fade-out; }
  .sg-siteheader-content[data-dir], .sg-siteheader-content.is-exit { animation: none; }
  .sg-siteheader-content.is-exit { display: none; }
  .sg-siteheader-hover { transition: opacity var(--duration-instant) linear; }
  .sg-siteheader-chev, .sg-siteheader-item.is-open .sg-siteheader-chev { transition: none; }
}
@media (pointer: coarse) {
  /* the items are 40px tall and only shown from 1024px up (a laptop with a touch screen): their reach is stretched to 44px; the menu button and rows are 44px+ already */
  .sg-siteheader-item::before { content: ""; position: absolute; inset: -2px 0; }
  .sg-siteheader-link { min-height: 44px; }
}

/* ---------- Slider: 6px track (mist-200 + 1px line-strong), ink fill, a ring-edged thumb, an ink bubble while it is held ---------- */
/* container-type makes the content width count as 0, so in a flex row (or an inline-block, a grid auto column) the slider would collapse: it asks to fill the row and never goes below 160px */
.sg-slider { container-type: inline-size; --sg-thumb: 24px; --sg-track: 6px; --sg-slider-h: var(--control-md); position: relative; display: block; flex: 1 1 auto; min-width: 160px; color: var(--ink); font-size: 15px; }
.sg-slider--sm { --sg-thumb: 20px; --sg-track: 4px; --sg-slider-h: var(--control-sm); font-size: 14px; }
.sg-slider-row { display: flex; align-items: flex-start; gap: var(--space-4); }
.sg-slider-main { flex: 1; min-width: 0; }
.sg-slider-control { position: relative; height: var(--sg-slider-h); touch-action: pan-y; cursor: pointer; user-select: none; -webkit-user-select: none; -webkit-tap-highlight-color: transparent; }
.sg-slider-bar { position: absolute; left: 0; right: 0; top: 50%; height: var(--sg-track); margin-top: calc(var(--sg-track) / -2); box-sizing: border-box; border-radius: var(--radius-pill);
  background: var(--mist-200); border: 1px solid var(--line-strong); }
/* the rail is the bar without the thumb's half width at each end: left % of the rail = the thumb's centre */
.sg-slider-rail { position: absolute; top: 0; bottom: 0; left: calc(var(--sg-thumb) / 2); right: calc(var(--sg-thumb) / 2); }
.sg-slider-fill { position: absolute; top: 50%; height: var(--sg-track); margin-top: calc(var(--sg-track) / -2); border-radius: var(--radius-pill); background: var(--ink); pointer-events: none; }
.sg-slider-dot { position: absolute; top: 50%; width: 3px; height: 3px; margin: -1.5px 0 0 -1.5px; border-radius: 50%; background: var(--ink-3); pointer-events: none; }
.sg-slider--sm .sg-slider-dot { width: 2px; height: 2px; margin: -1px 0 0 -1px; }
.sg-slider-dot.is-on { background: var(--ink-inverse); opacity: .7; }

.sg-slider-thumb { position: absolute; z-index: 1; top: 50%; width: var(--sg-thumb); height: var(--sg-thumb); margin-top: calc(var(--sg-thumb) / -2); box-sizing: border-box; border-radius: var(--radius-pill);
  background: var(--ink-inverse); border: 2px solid var(--ink); box-shadow: var(--shadow-lift); transform: translateX(-50%); outline: none; cursor: grab;
  transition: width var(--duration-spring) var(--ease-spring-bouncy), box-shadow var(--duration-quick) var(--ease-liquid); }
.sg-slider-thumb.is-top { z-index: 2; }
/* held: it stretches sideways like Switch's thumb, and springs back when let go */
.sg-slider-thumb.is-dragging { width: calc(var(--sg-thumb) * 1.25); cursor: grabbing; transition: width var(--duration-base) var(--ease-liquid), box-shadow var(--duration-quick) var(--ease-liquid); }
.sg-slider-thumb.is-kb { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-slider-control:active { cursor: grabbing; }

/* recipe G: ink bubble, 12px, 6 x 10, radius-xs, 8px above the thumb, no arrow */
.sg-slider-tip { position: absolute; left: 50%; bottom: calc(100% + 8px); max-width: 240px; padding: 6px 10px; box-sizing: border-box; border-radius: var(--radius-xs);
  background: var(--ink); color: var(--ink-inverse); box-shadow: var(--shadow-lift); font-size: 12px; line-height: 18px; font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; text-align: center;
  pointer-events: none; opacity: 0; transform: translate(calc(-50% + var(--sg-tip-dx, 0px)), 4px) scale(.96); transform-origin: 50% 100%;
  transition: opacity calc(var(--duration-quick) * 2 / 3) var(--ease-exit), transform calc(var(--duration-quick) * 2 / 3) var(--ease-exit); }
.sg-slider-thumb.is-dragging .sg-slider-tip, .sg-slider-thumb.is-tip .sg-slider-tip { opacity: 1; transform: translate(calc(-50% + var(--sg-tip-dx, 0px)), 0); transition: opacity var(--duration-quick) var(--ease-liquid), transform var(--duration-quick) var(--ease-liquid); }

.sg-slider-marks { position: relative; height: 18px; margin: -4px calc(var(--sg-thumb) / 2) 0; font-size: 12px; line-height: 16px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-slider-mark { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.sg-slider-mark.is-start { left: calc(var(--sg-thumb) / -2); transform: none; }
.sg-slider-mark.is-end { right: calc(var(--sg-thumb) / -2); transform: none; }
.sg-slider-value { flex: none; align-self: flex-start; min-height: var(--sg-slider-h); display: inline-flex; align-items: center; justify-content: flex-end; font-size: 15px; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ink); }
.sg-slider--sm .sg-slider-value { font-size: 14px; }

/* narrow containers (a phone column): the readout moves above the track instead of squeezing it */
@container (max-width: 320px) {
  .sg-slider-row { flex-wrap: wrap; gap: 0; }
  .sg-slider-value { order: -1; flex: 1 0 100%; min-width: 0 !important; min-height: 0; justify-content: flex-start; margin-bottom: -2px; }
  .sg-slider-main { flex: 1 1 100%; }
}

@media (hover: hover) {
  .sg-slider:not(.is-disabled) .sg-slider-thumb:hover { box-shadow: var(--shadow-lift), 0 0 0 6px var(--state-hover); }
  .sg-slider:not(.is-disabled) .sg-slider-thumb.is-dragging:hover { box-shadow: var(--shadow-lift), 0 0 0 6px var(--state-pressed); }
  .sg-slider:not(.is-disabled) .sg-slider-thumb.is-kb:hover { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
}
.sg-slider.is-invalid .sg-slider-fill { background: var(--status-bad); }
.sg-slider.is-invalid .sg-slider-thumb { border-color: var(--status-bad); }
.sg-slider.is-invalid .sg-slider-thumb.is-kb { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--status-bad); }
@media (hover: hover) { .sg-slider.is-invalid:not(.is-disabled) .sg-slider-thumb.is-kb:hover { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--status-bad); } }
.sg-slider.is-disabled { opacity: var(--disabled); }
.sg-slider.is-disabled .sg-slider-control, .sg-slider.is-disabled .sg-slider-thumb { cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) {
  .sg-slider-thumb, .sg-slider-thumb.is-dragging { transition-property: box-shadow; }
  .sg-slider-thumb.is-dragging { width: var(--sg-thumb); }
  .sg-slider-tip, .sg-slider-thumb.is-dragging .sg-slider-tip, .sg-slider-thumb.is-tip .sg-slider-tip { transform: translate(calc(-50% + var(--sg-tip-dx, 0px)), 0); transition-property: opacity; }
}
@media (pointer: coarse) {
  /* the 32px small slider gets 6px more above and below: a finger lands anywhere in a 44px band */
  .sg-slider--sm .sg-slider-control::before { content: ""; position: absolute; left: 0; right: 0; top: -6px; bottom: -6px; }
}

/* ---------- SocialLogin: round glass buttons (IconButton md) or full-width Buttons; the platform's own mark sits inside, uncoloured by us ---------- */
.sg-social { display: grid; min-width: 0; }
.sg-social .sg-social-divider { margin: 0 0 var(--space-4); }
.sg-social-row { display: flex; justify-content: center; flex-wrap: wrap; gap: var(--space-6); }
.sg-social-list { display: grid; gap: var(--space-3); }
.sg-social-mark { flex: none; width: 24px; height: 24px; display: inline-grid; place-items: center; line-height: 0; }
.sg-social-mark > * { max-width: 100%; max-height: 100%; }
.sg-social-b .sg-social-mark { width: 20px; height: 20px; }
.sg-iconbtn--sm.sg-social-btn .sg-social-mark { width: 18px; height: 18px; }
.sg-social--icons .sg-social-btn { flex: none; }
/* while one platform is signing in, the others wait: dimmer, still focusable, nothing to press */
.sg-social-btn.is-dim, .sg-social-b.is-dim { opacity: var(--disabled); cursor: default; }
.sg-social-btn[aria-busy="true"] { cursor: progress; }

@media (prefers-reduced-motion: reduce) {
  /* the busy dots stop pulsing (core), nothing else here moves */
}
@media (pointer: coarse) {
  /* round buttons are 44px; the sm ones (32px) get the IconButton sm reach from core */
  .sg-iconbtn--sm.sg-social-btn { position: relative; }
  .sg-iconbtn--sm.sg-social-btn::after { content: ""; position: absolute; inset: -7px; }
}

/* ---------- Sparkline (uses the data-colour variables and .sg-ch--nebula from the BarChart slice) ---------- */
.sg-spark { display: inline-block; vertical-align: middle; line-height: 0; color: var(--sg-ch-ink, var(--ink)); }
.sg-spark--fill { display: block; width: 100%; }
.sg-spark svg { display: block; overflow: visible; }
.sg-spark-line { fill: none; stroke: var(--c); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.sg-spark-area { fill: color-mix(in srgb, var(--c) 10%, transparent); stroke: none; }
/* the reference interval (a target or normal range) is neutral, so it never competes with the series colour */
.sg-spark-band { fill: color-mix(in srgb, var(--sg-ch-ink, var(--ink)) 8%, transparent); }
.sg-spark-dot, .sg-spark-lone { fill: var(--c); }
.sg-spark-empty { stroke: var(--sg-ch-ink-2, var(--ink-2)); stroke-width: 1.5; stroke-linecap: round; stroke-dasharray: .1 5; fill: none; }
.sg-spark[role="status"] { display: inline-flex; flex-direction: column; justify-content: center; }
.sg-spark--fill[role="status"] { display: flex; }
.sg-spark-skel { display: block; width: 100%; height: 8px; border-radius: var(--radius-pill); }
/* data change: the line draws in from the left, the end dot arrives with it (never on the first render) */
@keyframes sg-spark-draw { from { clip-path: inset(-20% 100% -20% 0); } to { clip-path: inset(-20% 0 -20% 0); } }
@keyframes sg-spark-dot { from { opacity: 0; transform: scale(.4); } }
.sg-spark g.is-draw { animation: sg-spark-draw var(--duration-slow) var(--ease-liquid) both; }
.sg-spark g.is-draw .sg-spark-dot { transform-box: fill-box; transform-origin: center; animation: sg-spark-dot var(--duration-base) var(--ease-spring-bouncy) backwards; animation-delay: calc(var(--duration-slow) * .75); }

@media (prefers-reduced-motion: reduce) {
  .sg-spark g.is-draw, .sg-spark g.is-draw .sg-spark-dot { animation: none !important; }
}
@media (pointer: coarse) {
  /* not interactive: nothing to enlarge */
}

/* ---------- Splitter: panes sized in % through a registered property, 12px bars that draw as a 1px line (2px ink-2 when hovered, focused or dragged) ---------- */
@property --sg-pane-size { syntax: "<number>"; inherits: false; initial-value: 50; }

.sg-split { display: flex; flex-direction: row; box-sizing: border-box; width: 100%; height: 100%; min-width: 0; min-height: 0; }
.sg-split.is-vertical { flex-direction: column; }
/* basis = the pane's share; it may shrink when the min sizes of its neighbours need the room */
.sg-split-pane { position: relative; box-sizing: border-box; flex: 0 1 calc(var(--sg-pane-size) * 1%); min-width: 0; min-height: 0; overflow: auto; }
.sg-split-pane[data-collapsed] { overflow: hidden; }
/* closing and reopening a whole pane glides on the soft spring; dragging never animates */
.sg-split.is-snapping .sg-split-pane { transition: --sg-pane-size var(--duration-base) var(--ease-spring-soft); }
.sg-split.is-dragging { user-select: none; -webkit-user-select: none; }
.sg-split.is-dragging > .sg-split-pane { pointer-events: none; }

/* the bar: 12px to grab, net 0 in the layout (negative margins), the line itself is drawn in the middle */
.sg-split-handle { position: relative; z-index: 2; flex: none; box-sizing: border-box; outline: none; touch-action: none; -webkit-tap-highlight-color: transparent; }
.sg-split:not(.is-vertical) > .sg-split-handle { width: 12px; margin: 0 -6px; cursor: col-resize; }
.sg-split.is-vertical > .sg-split-handle { height: 12px; margin: -6px 0; cursor: row-resize; }
.sg-split-line { position: absolute; pointer-events: none; background: var(--line); transition: background-color var(--duration-quick) var(--ease-liquid); }
.sg-split:not(.is-vertical) .sg-split-line { top: 0; bottom: 0; left: 50%; width: 1px; margin-left: -.5px; }
.sg-split.is-vertical .sg-split-line { left: 0; right: 0; top: 50%; height: 1px; margin-top: -.5px; }
.sg-split-handle:hover .sg-split-line, .sg-split-handle:focus-visible .sg-split-line, .sg-split-handle.is-active .sg-split-line { background: var(--ink-2); }
.sg-split:not(.is-vertical) .sg-split-handle:hover .sg-split-line, .sg-split:not(.is-vertical) .sg-split-handle:focus-visible .sg-split-line, .sg-split:not(.is-vertical) .sg-split-handle.is-active .sg-split-line { width: 2px; margin-left: -1px; }
.sg-split.is-vertical .sg-split-handle:hover .sg-split-line, .sg-split.is-vertical .sg-split-handle:focus-visible .sg-split-line, .sg-split.is-vertical .sg-split-handle.is-active .sg-split-line { height: 2px; margin-top: -1px; }
.sg-split-handle:focus-visible .sg-split-line { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }

/* grip: a 4 x 24 pill in the middle of the bar, always shown */
.sg-split-grip { position: absolute; left: 50%; top: 50%; pointer-events: none; border-radius: var(--radius-pill); background: var(--line-strong); transition: background-color var(--duration-quick) var(--ease-liquid); }
.sg-split:not(.is-vertical) .sg-split-grip { width: 4px; height: 24px; margin: -12px 0 0 -2px; }
.sg-split.is-vertical .sg-split-grip { width: 24px; height: 4px; margin: -2px 0 0 -12px; }
.sg-split-handle:hover .sg-split-grip, .sg-split-handle:focus-visible .sg-split-grip, .sg-split-handle.is-active .sg-split-grip { background: var(--ink-2); }

@media (prefers-reduced-motion: reduce) {
  /* the pane jumps shut instead of gliding; colours still change */
  .sg-split.is-snapping .sg-split-pane { transition: none; }
}
@media (pointer: coarse) {
  /* the bar is 24px wide to grab with a finger (the line stays 1px) */
  .sg-split:not(.is-vertical) > .sg-split-handle { width: 24px; margin: 0 -12px; }
  .sg-split.is-vertical > .sg-split-handle { height: 24px; margin: -12px 0; }
}

/* ---------- Steps: 28 px markers joined by a 2 px connector (dashed line-strong ahead, ink behind). Title 13/500, description 12. ---------- */
.sg-steps { list-style: none; margin: 0; padding: 0; display: flex; color: var(--ink); }
.sg-steps--v { flex-direction: column; }
.sg-step { position: relative; min-width: 0; }
.sg-step-head { display: flex; align-items: center; gap: var(--space-2); }

/* marker */
.sg-step-mark { position: relative; box-sizing: border-box; flex: none; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
  border: 1.5px solid var(--line-strong); background: var(--glass); color: var(--ink-2);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm));
  font-family: var(--font-mono); font-size: 12px; line-height: 1; font-weight: 500; font-variant-numeric: tabular-nums;
  transition: background-color var(--duration-base) var(--ease-liquid), border-color var(--duration-base) var(--ease-liquid), color var(--duration-base) var(--ease-liquid), box-shadow var(--duration-base) var(--ease-liquid), transform var(--duration-quick) var(--ease-liquid); }
.sg-step-mark .sg-icon { width: 16px; height: 16px; stroke-width: 2; }
.sg-step[data-state="done"] .sg-step-mark { background: var(--ink); border-color: var(--ink); color: var(--ink-inverse); -webkit-backdrop-filter: none; backdrop-filter: none; }
/* current and loading: a 2 px ink ring around a solid disc (recipe C), a 2 px gap of glass between the two. The gap is what tells it from a finished step: in the dark theme the ring, the disc and the
   finished marker are all the same bright colour, and a ring flush against the disc would vanish into it. The number is ink on white, or dark on the bright disc in the dark theme */
.sg-step-mark::before { content: ""; position: absolute; z-index: -1; inset: 2px; border-radius: 50%; background: var(--solid); opacity: 0; pointer-events: none;
  transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-step[data-state="current"] .sg-step-mark, .sg-step[data-status="loading"] .sg-step-mark { isolation: isolate; border: 2px solid var(--ink); box-shadow: var(--shadow-lift); color: var(--ink); color: light-dark(var(--ink), var(--ink-inverse)); }
.sg-step[data-state="current"] .sg-step-mark::before, .sg-step[data-status="loading"] .sg-step-mark::before { opacity: 1; }
.sg-step[data-status="error"] .sg-step-mark { background: var(--status-bad); border: 2px solid var(--status-bad); box-shadow: var(--shadow-lift); color: var(--on-status-bad); -webkit-backdrop-filter: none; backdrop-filter: none; }   /* a filled disc, not a ringed one: status-bad on the bright solid disc would be 2:1 in the dark theme */
.sg-step[data-status="error"] .sg-step-mark::before { opacity: 0; }

/* connector: dashed behind a 2 px ink bar that grows when the step before it is done */
.sg-step-line { position: relative; overflow: hidden; flex: 1; min-width: 0;
  background: repeating-linear-gradient(90deg, var(--line-strong) 0 4px, transparent 4px 8px); }
.sg-step-fill { position: absolute; inset: 0; background: var(--ink); transform: scaleX(0); transform-origin: left center;
  transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-step[data-state="done"] .sg-step-fill { transform: scaleX(1); }

/* text */
.sg-step-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: start; }
.sg-step-title { font-size: 13px; line-height: 20px; font-weight: 500; color: var(--ink-2); overflow-wrap: anywhere; }
.sg-step[data-state="done"] .sg-step-title, .sg-step[data-state="current"] .sg-step-title { color: var(--ink); }
.sg-step-desc { max-width: 28em; font-size: 12px; line-height: 18px; color: var(--ink-2); overflow-wrap: anywhere; }
.sg-step[data-status="error"] .sg-step-desc { color: var(--status-bad); }

/* horizontal: marker + connector on top, text underneath, left-aligned with the marker */
.sg-steps--h .sg-step { flex: 1 1 0; display: flex; flex-direction: column; gap: 10px; }
.sg-steps--h .sg-step-line { height: 2px; margin-right: var(--space-2); }
.sg-steps--h .sg-step-body { padding-right: var(--space-3); }
.sg-steps--h .sg-step-btn, .sg-steps--h .sg-step-cur { padding: 4px var(--space-2); margin: -4px var(--space-1) -4px calc(-1 * var(--space-2)); }   /* room for the focus ring around the text; the negative margin keeps the text where it was, and the 4 px on the right keeps the ring off the next step's title */

/* vertical: markers in a column with the connector running down between them, text to the right */
.sg-steps--v .sg-step { display: grid; grid-template-columns: 28px minmax(0, 1fr); column-gap: var(--space-3); }
.sg-steps--v .sg-step-head { flex-direction: column; gap: var(--space-1); }
.sg-steps--v .sg-step-line { width: 2px; min-height: 20px; margin-bottom: var(--space-1);
  background: repeating-linear-gradient(180deg, var(--line-strong) 0 4px, transparent 4px 8px); }
.sg-steps--v .sg-step-fill { transform: scaleY(0); transform-origin: center top; }
.sg-steps--v .sg-step[data-state="done"] .sg-step-fill { transform: scaleY(1); }
.sg-steps--v .sg-step-body { margin: 4px 0 var(--space-6); }   /* 4 px down: the 20 px title line centres on the 28 px marker; the margin, not padding, carries the gap so a button's ring hugs its text */
.sg-steps--v .sg-step:last-child .sg-step-body { margin-bottom: 0; }
.sg-steps--v .sg-step-btn, .sg-steps--v .sg-step-cur { padding: 4px var(--space-2); margin: 0 0 20px calc(-1 * var(--space-2)); }   /* no negative margin on the right: it would push the list's scroll width past its box */
.sg-steps--v .sg-step:last-child .sg-step-btn, .sg-steps--v .sg-step:last-child .sg-step-cur { margin-bottom: -4px; }

/* going back: finished steps are buttons. The current step's text takes the same box (and a focus ring of its own): when a keyboard user goes back, the focus lands there */
.sg-step-btn, .sg-step-cur { position: relative; border-radius: var(--radius-xs); -webkit-tap-highlight-color: transparent; }
.sg-step-btn { cursor: pointer; }
.sg-step.is-click .sg-step-mark { cursor: pointer; }
.sg-step.is-click:hover .sg-step-mark { box-shadow: var(--shadow-lift); }
.sg-step.is-click:hover .sg-step-title { text-decoration: underline; text-decoration-color: var(--line-strong); text-decoration-thickness: 1px; text-underline-offset: 3px; }
.sg-step.is-click:active .sg-step-mark { transform: scale(.92); }

@media (prefers-reduced-motion: reduce) {
  /* the ink fills the connector with a fade instead of a slide; colours still change, nothing grows, nothing shrinks */
  .sg-step-fill, .sg-steps--v .sg-step-fill { transform: none; opacity: 0; transition: opacity var(--duration-quick) var(--ease-liquid); }
  .sg-step[data-state="done"] .sg-step-fill, .sg-steps--v .sg-step[data-state="done"] .sg-step-fill { transform: none; opacity: 1; }
  .sg-step-mark { transition-property: background-color, border-color, color !important; }
  .sg-step-mark::before { transition-duration: var(--duration-instant); }
  .sg-step.is-click:active .sg-step-mark { transform: none; }
}
@media (pointer: coarse) {
  /* a finished step is a 44 px target on its text and on its marker */
  .sg-step-btn::after { content: ""; position: absolute; inset: -10px 0 -10px -6px; }   /* nothing sticks out on the right: the button is as wide as its step, and an overhang would widen the list */
  /* the marker has a 1.5–2 px border and the pseudo-element starts at its padding edge, so it reaches 10 px out to make 44+ */
  .sg-step.is-click .sg-step-mark::after { content: ""; position: absolute; inset: -10px; border-radius: 50%; }
}

/* ---------- SwipeCell: the row and its action panels sit on one track; the track slides, the clip hides what is off to the side ---------- */
.sg-swipe { position: relative; display: grid; grid-template-rows: 1fr; min-width: 0; margin: 0; padding: 0; list-style: none; color: var(--ink);
  transition: grid-template-rows var(--duration-smooth) var(--ease-spring-soft), visibility 0s; }
/* removed by the caller: the row folds shut (2/3 of the time), then leaves the accessibility tree and the tab order */
.sg-swipe.is-removed { grid-template-rows: 0fr; visibility: hidden;
  transition: grid-template-rows calc(var(--duration-smooth) * 2 / 3) var(--ease-exit), visibility 0s linear calc(var(--duration-smooth) * 2 / 3); }
/* a hairline between neighbouring cells; --sg-swipe-inset moves its start to the text edge */
.sg-swipe + .sg-swipe::before { content: ""; position: absolute; z-index: 2; top: 0; left: var(--sg-swipe-inset, 0px); right: 0; height: 1px; background: var(--line); pointer-events: none; }
.sg-swipe-clip { position: relative; min-height: 0; overflow: clip; }
.sg-swipe-track { position: relative; }
.sg-swipe.is-swipe .sg-swipe-track { transition: transform var(--duration-smooth) var(--ease-spring-soft); will-change: transform; }
.sg-swipe-content { position: relative; min-width: 0; outline: none; }
.sg-swipe.is-swipe .sg-swipe-content { touch-action: pan-y; -webkit-tap-highlight-color: transparent; }
.sg-swipe[data-drag] .sg-swipe-content { -webkit-user-select: none; user-select: none; }

/* touch: the action panels hang off the track, just outside the row (the first action sits next to the row) */
.sg-swipe-panel { position: absolute; top: 0; bottom: 0; display: flex; }
.sg-swipe-panel--right { left: 100%; }
.sg-swipe-panel--left { right: 100%; }
.sg-swipe-act { position: relative; flex: 0 0 auto; display: flex; align-items: stretch; justify-content: center; box-sizing: border-box; min-width: 72px; margin: 0; padding: 0 var(--space-4); border: 0; border-radius: 0;
  background: var(--ink); color: var(--ink-inverse); font: inherit; font-size: 13px; line-height: 18px; font-weight: 500; white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.sg-swipe-act.is-muted { background: var(--mist-200); color: var(--ink); }
.sg-swipe-act.is-danger { z-index: 1; isolation: isolate; background: var(--status-bad); color: var(--on-status-bad); }
.sg-swipe-lab { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; transition: transform var(--duration-smooth) var(--ease-spring-soft); }
.sg-swipe-act .sg-icon { width: 18px; height: 18px; }
.sg-swipe-act:active { filter: brightness(.92); }
.sg-swipe-act.sg-focusable:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-halo), inset 0 0 0 4px var(--focus-ring); }
.sg-swipe-act.is-busy { cursor: progress; }
.sg-swipe-act .sg-busy { color: inherit; }
/* 2-step danger: on the first press the danger fill grows over the whole panel (clip-path, from its own slot to the panel's full width) and the label moves to the middle */
.sg-swipe-act.is-danger::before { content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; right: 0; left: calc(var(--sg-sw-l, 0px) * -1); background: var(--status-bad);
  clip-path: inset(0 0 0 var(--sg-sw-l, 0px)); transition: clip-path var(--duration-smooth) var(--ease-spring-soft); }
.sg-swipe-act.is-danger.is-confirm::before { clip-path: inset(0); }
.sg-swipe-act.is-confirm .sg-swipe-lab { transform: translateX(var(--sg-sw-s, 0px)); }

/* mouse: the same actions at the row's end, shown on hover and while focus is in the row; always in the tab order. Overlay glass (recipe D), over a mist-100 underlay: it covers whatever the row has at its end. A backdrop-filter nested inside the glass list or card cannot blur what is under it (Chrome only shows it what is behind both), so the underlay is what keeps a covered time or count from showing through */
.sg-swipe-inline { position: absolute; z-index: 3; top: 50%; right: var(--space-3); display: flex; align-items: center; gap: 2px; padding: 2px; transform: translateY(-50%);
  border-radius: var(--radius-sm); background: linear-gradient(var(--glass-overlay), var(--glass-overlay)), var(--mist-100); border: 1px solid var(--line); box-shadow: var(--shadow-float);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4); opacity: 0; transition: opacity var(--duration-quick) var(--ease-liquid); }
.sg-swipe:hover .sg-swipe-inline, .sg-swipe:focus-within .sg-swipe-inline, .sg-swipe-inline.is-pinned { opacity: 1; }
@media (hover: none) { .sg-swipe-inline { opacity: 1; } }
.sg-swipe-inline .sg-btn--ghost { border-color: transparent; }
.sg-swipe-ia.is-danger { color: var(--status-bad); }

@media (prefers-reduced-motion: reduce) {
  /* no spring and no growing: the row jumps to where it belongs; the danger fill and label still change */
  .sg-swipe, .sg-swipe.is-removed { transition: visibility 0s; }
  .sg-swipe.is-swipe .sg-swipe-track { transition: none; }
  .sg-swipe-act.is-danger::before, .sg-swipe-lab { transition: none; }
  .sg-swipe-inline { transition-duration: 0s; }
}
@media (pointer: coarse) {
  /* the panels are as tall as the row and at least 72px wide; nothing here is smaller than a finger */
}

/* ---------- TabBar: glass capsule 12 px above the bottom edge + safe area; the current item rides a solid capsule (recipe C) on the soft spring ---------- */
.sg-tabbar { box-sizing: border-box; width: 100%; left: 0; right: 0; bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px)); z-index: var(--z-sticky);
  display: flex; justify-content: center; padding: 0 var(--space-3); pointer-events: none; }   /* the strip passes taps through; only the capsule takes them */
.sg-tabbar[data-position="fixed"] { position: fixed; }
.sg-tabbar[data-position="absolute"] { position: absolute; }
.sg-tabbar[data-position="static"] { position: relative; bottom: auto; }
.sg-tabbar-bar { position: relative; box-sizing: border-box; width: min(100%, calc(var(--sg-tabbar-n, 4) * 76px + 12px)); padding: 6px; border-radius: var(--radius-pill); color: var(--ink); pointer-events: auto;
  background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4);
  --sg-badge-ring: var(--mist-100); }
.sg-tabbar-list { list-style: none; margin: 0; padding: 0; display: flex; }
.sg-tabbar-li { flex: 1 1 0; min-width: 0; display: flex; }
.sg-tabbar .sg-tabbar-badge { display: flex; width: 100%; }
.sg-tabbar-item { position: relative; z-index: 1; box-sizing: border-box; flex: 1; min-width: 0; height: 52px; margin: 0; padding: 0 2px; border: 0; border-radius: var(--radius-pill);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  background: transparent; color: var(--ink-2); font: inherit; font-size: 12px; line-height: 16px; font-weight: 500; text-decoration: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: color var(--duration-base), transform var(--duration-quick) var(--ease-liquid); }
.sg-tabbar-item .sg-icon { width: 22px; height: 22px; }
.sg-tabbar-label { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-tabbar-item:not(.is-current):not(.is-disabled):hover { color: var(--ink); }
.sg-tabbar-item:not(.is-disabled):active { transform: scale(.94); }
.sg-tabbar-item.is-current { color: var(--ink); color: light-dark(var(--ink), var(--ink-inverse)); }
.sg-tabbar-item.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
/* the badge sits on the icon's top-right corner, not the cell's: its left edge 4 px right of the cell's middle, its centre 9 px below the top. Anchored by the left edge, a wide
   count ("99+") grows outwards instead of covering the icon; a one-digit count lands where a centred one would (centre 13 px right), a dot is nudged to the same spot */
.sg-tabbar .sg-tabbar-badge .sg-badge.is-pinned { top: 9px; right: auto; left: calc(50% + 4px); translate: 0 -50%; }
.sg-tabbar .sg-tabbar-badge .sg-badge--dot.is-pinned { left: calc(50% + 9px); }

.sg-tabbar-ind { position: absolute; z-index: 0; top: 0; left: 0; border-radius: var(--radius-pill); background: var(--solid); box-shadow: var(--shadow-lift); pointer-events: none;
  transition: transform var(--duration-spring) var(--ease-spring-soft), width var(--duration-spring) var(--ease-spring-soft); }
.sg-tabbar-ind.is-still { transition: none; }

@media (prefers-reduced-motion: reduce) {
  /* the capsule jumps instead of gliding; the press does not shrink */
  .sg-tabbar-item { transition-property: color, opacity !important; }
  .sg-tabbar-ind { transition: none; }
}
@media (pointer: coarse) {
  /* cells are 52 px tall and over 56 px wide even with five items on a 320 px screen: already past 44; no double-tap zoom */
  .sg-tabbar-item { touch-action: manipulation; }
}

/* ---------- Table: recipe F surface. Header 40px, rows row-md 52 (sm: row-sm 40), hairlines between rows, tabular numerals, numbers right-aligned ---------- */
.sg-table { position: relative; isolation: isolate; min-width: 0; overflow: hidden; border-radius: var(--radius-md); color: var(--ink); font-size: 15px; line-height: 22px;
  background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass);
  -webkit-backdrop-filter: blur(var(--blur-md)) saturate(1.4); backdrop-filter: blur(var(--blur-md)) saturate(1.4); }
.sg-table--bare { overflow: visible; border-radius: 0; background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.sg-table-frame { position: relative; }
.sg-table-scroll { overflow: auto; max-height: var(--sg-table-h, none); overscroll-behavior-x: contain; }
.sg-table-scroll:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--focus-ring), inset 0 0 0 4px var(--focus-halo); }
.sg-table-table { width: 100%; min-width: var(--sg-table-min, 0); border-collapse: separate; border-spacing: 0; table-layout: auto; }

/* header cells */
.sg-table-th { box-sizing: border-box; height: 40px; padding: 0 var(--space-4); text-align: start; white-space: nowrap; font-size: 13px; line-height: 18px; font-weight: 500; color: var(--ink-2); background: transparent; border-bottom: 1px solid var(--line); }
.sg-table-th.is-end, .sg-table-td.is-end { text-align: end; }
.sg-table-th.is-center, .sg-table-td.is-center { text-align: center; }
.sg-table-sort { display: inline-flex; align-items: center; gap: 2px; box-sizing: border-box; height: 28px; margin: 0 -8px; padding: 0 6px 0 8px; border: 0; border-radius: var(--radius-xs); background: transparent;
  color: inherit; font: inherit; font-size: 13px; line-height: 18px; font-weight: 500; white-space: nowrap; cursor: pointer; transition: background-color var(--duration-instant) var(--ease-liquid), color var(--duration-instant) var(--ease-liquid); }
.sg-table-sort.is-end { flex-direction: row-reverse; padding: 0 8px 0 6px; }
.sg-table-sort:hover { background: var(--state-hover); color: var(--ink); }
.sg-table-sort:active { background: var(--state-pressed); }
.sg-table-sort .sg-icon { width: 14px; height: 14px; color: var(--ink-3); }
.sg-table-sort.is-sorted { color: var(--ink); }
.sg-table-sort.is-sorted .sg-icon { color: var(--ink); }

/* body cells */
.sg-table-td { box-sizing: border-box; height: var(--row-md); padding: 8px var(--space-4); vertical-align: middle; white-space: nowrap; border-bottom: 1px solid var(--line); background: transparent; }
.sg-table-td.is-wrap { white-space: normal; min-width: 200px; }
th.sg-table-td { font-weight: 500; text-align: start; }
/* names and codes keep their normal digits ("Juno-118", not "Juno-1 1 8"); only the number columns (type="number", or aligned to the end) are set in tabular numerals */
.sg-table-td, .sg-table-th { font-variant-numeric: normal; }
.sg-table-td.is-end, .sg-table-th.is-end, .sg-table-td.is-num, .sg-table-th.is-num { font-variant-numeric: tabular-nums; }
.is-sm .sg-table-td { height: var(--row-sm); padding-block: 4px; font-size: 13px; line-height: 18px; }
.sg-table-row:last-child > .sg-table-td { border-bottom: 0; }
.sg-table-row:hover > .sg-table-td { background-image: linear-gradient(var(--state-hover), var(--state-hover)); }
.sg-table-row.is-selected > .sg-table-td { background-image: linear-gradient(var(--state-selected), var(--state-selected)); }
.sg-table-row.is-selected:hover > .sg-table-td { background-image: linear-gradient(var(--state-hover), var(--state-hover)), linear-gradient(var(--state-selected), var(--state-selected)); }
.sg-table-row.is-skeleton:hover > .sg-table-td { background-image: none; }
.sg-table-row.is-clickable { cursor: pointer; }
.sg-table-row.is-clickable:focus-visible { outline: none; }
/* keyboard focus on a clickable row: the system's double ring (outer focus-ring 2px, inner focus-halo 2px) drawn inside the row — each cell paints its top and bottom edge, the first one the left, the last one the right */
.sg-table-row.is-clickable:focus-visible > .sg-table-td { background-image: linear-gradient(var(--state-hover), var(--state-hover));
  --rg-l: inset 0 0 0 0 transparent; --rg-r: inset 0 0 0 0 transparent; --hl-l: inset 0 0 0 0 transparent; --hl-r: inset 0 0 0 0 transparent;
  box-shadow: inset 0 2px 0 0 var(--focus-ring), inset 0 -2px 0 0 var(--focus-ring), var(--rg-l), var(--rg-r), inset 0 4px 0 0 var(--focus-halo), inset 0 -4px 0 0 var(--focus-halo), var(--hl-l), var(--hl-r); }
.sg-table-row.is-clickable:focus-visible > .sg-table-td:first-child { --rg-l: inset 2px 0 0 0 var(--focus-ring); --hl-l: inset 4px 0 0 0 var(--focus-halo); }
.sg-table-row.is-clickable:focus-visible > .sg-table-td:last-child { --rg-r: inset -2px 0 0 0 var(--focus-ring); --hl-r: inset -4px 0 0 0 var(--focus-halo); }
.sg-table-none { color: var(--ink-3); }
.sg-table-cell { display: flex; align-items: center; min-width: 0; }
.is-end > .sg-table-cell { justify-content: flex-end; }
.is-center > .sg-table-cell { justify-content: center; }
.sg-table-trunc { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-table-sel { width: 48px; min-width: 48px; padding: 0 0 0 var(--space-4); }
.sg-table-sel .sg-check-wrap { display: flex; align-items: center; }
.sg-table-sel .sg-check.is-bare { min-height: 20px; }
.sg-table-sel .sg-check.is-bare .sg-check-box { margin-top: 0; }
.sg-table-sel .sg-check.is-bare .sg-check-input { top: 0; }
.sg-table-emptycell { height: auto; padding: 0; white-space: normal; }
.sg-table-empty { position: sticky; left: 0; max-width: 100%; box-sizing: border-box; padding: var(--space-4) 0; }
.sg-table-empty .sg-empty { max-width: none; }
.sg-table-footer { padding: var(--space-3) var(--space-4); border-top: 1px solid var(--line); }
.sg-table--bare .sg-table-footer { padding-inline: 0; }
.sg-table--bare .sg-table-th:first-child, .sg-table--bare .sg-table-td:first-child { padding-left: 0; }
.sg-table--bare .sg-table-th:last-child, .sg-table--bare .sg-table-td:last-child { padding-right: 0; }
.sg-table--bare .sg-table-sel { padding-left: 0; }

/* row details: a closed detail row is 0 high; it opens like an Accordion panel (grid-template-rows 0fr → 1fr) */
.sg-table-exp { width: 44px; min-width: 44px; padding: 0 0 0 var(--space-3); }
.sg-table-th.sg-table-exp { padding-left: 0; }
.sg-table-expbtn .sg-icon { transition: transform calc(var(--duration-smooth) * 2 / 3) var(--ease-exit); }
.sg-table-expbtn.is-open .sg-icon { transform: rotate(90deg); transition: transform var(--duration-smooth) var(--ease-spring-soft); }
.sg-table-row.is-expanded > .sg-table-td { border-bottom-color: transparent; }
.sg-table-detail > .sg-table-detailcell { height: auto; padding: 0; white-space: normal; border-bottom: 1px solid var(--line); }
.sg-table-detail:not(.is-open) > .sg-table-detailcell, .sg-table-detail:last-child > .sg-table-detailcell { border-bottom: 0; }
/* closed: the whole row (tr, td and the panel inside) is visibility:hidden once the close has finished, so a screen reader does not count an empty row for every closed detail */
.sg-table-detail { visibility: hidden; transition: visibility 0s linear calc(var(--duration-smooth) * 2 / 3); }
.sg-table-detail.is-open { visibility: visible; transition: visibility 0s; }
.sg-table-detailpanel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows calc(var(--duration-smooth) * 2 / 3) var(--ease-exit); }
.sg-table-detail.is-open .sg-table-detailpanel { grid-template-rows: 1fr; transition: grid-template-rows var(--duration-smooth) var(--ease-spring-soft); }
.sg-table-detailclip { min-height: 0; overflow: hidden; }
.sg-table-detailbody { box-sizing: border-box; width: var(--sg-table-vw, 100%); max-width: 100%; padding: var(--space-1) var(--space-4) var(--space-4) calc(var(--space-4) + 44px); font-size: 15px; line-height: 22px; color: var(--ink-2);
  opacity: 0; transition: opacity calc(var(--duration-base) * 2 / 3) var(--ease-exit); }
.sg-table-detail.is-open .sg-table-detailbody { opacity: 1; transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-table--bare .sg-table-detailbody { padding-right: 0; }

/* sticky header: it floats over the rows as overlay glass once something has scrolled under it */
.has-sticky-head .sg-table-th { position: sticky; top: 0; z-index: 2; transition: background-color var(--duration-quick) var(--ease-liquid); }
.has-sticky-head[data-scroll-top="true"] .sg-table-th { background-color: var(--glass-overlay); }
/* the soft shadow under the stuck header is one strip across the visible width, stuck 40px (the header's height) from the top: a box-shadow on every cell breaks at the cell borders */
.has-sticky-head .sg-table-scroll::before { content: ""; display: block; position: sticky; top: 40px; left: 0; z-index: 2; box-sizing: border-box; width: var(--sg-table-vw, 100%); height: 12px; margin-bottom: -12px; pointer-events: none; opacity: 0;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--scrim) 35%, transparent), transparent); transition: opacity var(--duration-quick) var(--ease-liquid); }
.has-sticky-head[data-scroll-top="true"] .sg-table-scroll::before { opacity: 1; }
/* sticky columns: the table sets `left` (or `right`) from the measured header widths. They look like any other cell until content actually slides under them, then they turn to frosted glass so the rows moving by are blurred, not cut */
.sg-table-th.is-sticky, .sg-table-td.is-sticky { position: sticky; z-index: 1; }
.sg-table[data-scroll-start="true"] .is-sticky-start, .sg-table[data-scroll-end="true"] .is-sticky-end { background-color: var(--glass-overlay); }
/* the blur sits on a pseudo-element: Chrome does not apply backdrop-filter to a table cell itself */
.has-sticky-head .sg-table-th::before, .sg-table[data-scroll-start="true"] .is-sticky-start::before, .sg-table[data-scroll-end="true"] .is-sticky-end::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4); }
.has-sticky-head .sg-table-th.is-sticky { z-index: 3; }
.sg-table-th.is-edge-start::after, .sg-table-td.is-edge-start::after, .sg-table-th.is-edge-end::after, .sg-table-td.is-edge-end::after { content: ""; position: absolute; top: 0; bottom: -1px; width: 16px; pointer-events: none; opacity: 0; transition: opacity var(--duration-quick) var(--ease-liquid); }
.sg-table-th.is-edge-start::after, .sg-table-td.is-edge-start::after { right: -16px; background: linear-gradient(90deg, color-mix(in srgb, var(--scrim) 45%, transparent), transparent); }
.sg-table-th.is-edge-end::after, .sg-table-td.is-edge-end::after { left: -16px; background: linear-gradient(270deg, color-mix(in srgb, var(--scrim) 45%, transparent), transparent); }
.sg-table[data-scroll-start="true"] .is-edge-start::after, .sg-table[data-scroll-end="true"] .is-edge-end::after { opacity: 1; }
/* edge fades where nothing is stuck: a hint that there is more to scroll to */
.sg-table-frame::before, .sg-table-frame::after { content: ""; position: absolute; top: 0; bottom: 0; z-index: 4; width: 24px; pointer-events: none; opacity: 0; transition: opacity var(--duration-quick) var(--ease-liquid); }
.sg-table-frame::before { left: 0; background: linear-gradient(90deg, var(--scrim), transparent); }
.sg-table-frame::after { right: 0; background: linear-gradient(270deg, var(--scrim), transparent); }
.sg-table[data-scroll-start="true"]:not(.has-sticky-start) .sg-table-frame::before { opacity: 1; }
.sg-table[data-scroll-end="true"]:not(.has-sticky-end) .sg-table-frame::after { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .sg-table-detail, .sg-table-detail.is-open { transition: visibility 0s; }
  .sg-table-detailpanel, .sg-table-detail.is-open .sg-table-detailpanel { transition: none; }
  .sg-table-expbtn .sg-icon, .sg-table-expbtn.is-open .sg-icon { transition: none; }
  .sg-table-detailbody, .sg-table-detail.is-open .sg-table-detailbody { transition-property: opacity; transition-duration: var(--duration-quick); transition-timing-function: linear; }
  .sg-table-sort, .has-sticky-head .sg-table-th { transition-property: background-color, color, opacity; }
  .has-sticky-head .sg-table-scroll::before { transition-property: opacity; }
  .sg-table-frame::before, .sg-table-frame::after, .is-edge-start::after, .is-edge-end::after { transition-property: opacity; }
}
@media (pointer: coarse) {
  /* header sort buttons are 28px: a finger gets 44 */
  .sg-table-sort { position: relative; }
  .sg-table-sort::after { content: ""; position: absolute; inset: -8px 0; }
  .sg-table-td.is-sticky::after, .sg-table-th.is-sticky::after { pointer-events: none; }
}

/* ---------- TableOfContents: 1px rail, 13/20 links, a 2px ink bar on the heading being read (glides on the soft spring) ---------- */
.sg-toc { box-sizing: border-box; width: 220px; max-width: 100%; color: var(--ink); }
.sg-toc.is-compact { width: auto; max-width: 100%; }
.sg-toc-title { margin: 0 0 var(--space-3); font-size: 13px; line-height: 20px; font-weight: 500; color: var(--ink); }
.sg-toc-rail { position: relative; border-left: 1px solid var(--line); }
.sg-toc-list { list-style: none; margin: 0; padding: 0; }
.sg-toc-link { display: block; padding: 6px 0 6px 16px; border-radius: var(--radius-xs); color: var(--ink-2); font-size: 13px; line-height: 20px; font-weight: 400; text-decoration: none; overflow-wrap: anywhere; -webkit-tap-highlight-color: transparent;
  transition: color var(--duration-quick) var(--ease-liquid); }
.sg-toc-link.is-l3 { padding-left: 28px; }
.sg-toc-link:hover { color: var(--ink); }
.sg-toc-link.is-current { color: var(--ink); font-weight: 500; }
.sg-toc-ind { position: absolute; top: 0; left: -1px; width: 2px; border-radius: var(--radius-pill); background: var(--ink); pointer-events: none; transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-toc-ind.is-still { transition: none; }

/* folded: a ghost sm button "本页目录 · 当前章节名"; the list opens in a Popover with the same rail */
.sg-toc-trigger { max-width: 100%; }
.sg-toc-trigger-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-popover .sg-toc-rail { margin: 2px 0; }
.sg-popover .sg-toc-link { padding-right: 8px; }

@media (prefers-reduced-motion: reduce) {
  /* the bar jumps to the next heading; colours still change */
  .sg-toc-ind { transition: none; }
}
@media (pointer: coarse) {
  /* links in the folded list are 44px rows; the wide list is not shown on touch widths (it folds below 1024) */
  .sg-popover .sg-toc-link { padding-top: 12px; padding-bottom: 12px; }
}

/* ---------- Tabs: "line" = underline indicator that glides; "pill" reuses .sg-tabs / .sg-tab / .sg-tabs-ind from PillTabs ---------- */
.sg-tabbed { min-width: 0; }
.sg-tabbed--v { display: flex; align-items: flex-start; gap: var(--space-6); }
.sg-tabbed--v > .sg-tabbed-panel { flex: 1 1 0; min-width: 0; }
.sg-tabbed-bar { position: relative; min-width: 0; border-bottom: 1px solid var(--line); }
.sg-tabbed--pill > .sg-tabbed-bar { border-bottom: 0; }
.sg-tabbed-list { position: relative; box-sizing: border-box; display: flex; gap: var(--space-1); min-width: 100%; width: max-content; }

/* a tab: 44 high (sm 36), 12 either side, 15 / 500 ink-2; the current one is ink */
.sg-tabbed-tab--line { position: relative; flex: none; display: inline-flex; align-items: center; justify-content: center; height: 44px; margin: 0; padding: 0 var(--space-3); border: 0; border-radius: var(--radius-xs); background: none;
  font: inherit; font-size: 15px; font-weight: 500; line-height: 1; color: var(--ink-2); white-space: nowrap; cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: color var(--duration-quick) var(--ease-liquid); }
.sg-tabbed--sm .sg-tabbed-tab--line { height: 36px; font-size: 14px; }
.sg-tabbed-tab--line:hover, .sg-tabbed-tab--line[aria-selected="true"] { color: var(--ink); }
/* the ring is drawn inside the tab: the strip scrolls, so an outer ring would be cut off at its edge */
.sg-tabbed-tab--line:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--focus-ring), inset 0 0 0 4px var(--focus-halo); }
.sg-tabbed-tab[disabled] { opacity: var(--disabled); cursor: not-allowed; }
.sg-tabbed-in { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.sg-tabbed-label { min-width: 0; }
.sg-tabbed-icon { width: 16px; height: 16px; }

/* indicator: 2px ink, as wide as the tab's content; glides on the spring (the style attribute switches it off for the first paint and for resizes) */
.sg-tabbed-ind { position: absolute; z-index: 1; left: 0; bottom: 0; height: 2px; border-radius: var(--radius-pill); background: var(--ink); pointer-events: none;
  transition: transform var(--duration-spring) var(--ease-spring-soft), width var(--duration-spring) var(--ease-spring-soft), height var(--duration-spring) var(--ease-spring-soft); }
.sg-tabbed--v .sg-tabbed-ind { top: 0; bottom: auto; width: 2px; height: auto; }

/* fill: equal-width tabs across the bar (2–4 tabs on a phone) */
.sg-tabbed--fill .sg-tabbed-tab--line { flex: 1 1 0; min-width: max-content; }
.sg-tabbed--fill.sg-tabbed--pill .sg-tab { flex: 1 1 0; max-width: none; min-width: max-content; }

/* vertical: 200 wide, left-aligned, indicator on the left, a hairline on the right */
.sg-tabbed--v .sg-tabbed-list { flex: none; flex-direction: column; gap: 2px; width: min(200px, 40%); min-width: 0; border-right: 1px solid var(--line); box-sizing: border-box; }
.sg-tabbed--v .sg-tabbed-tab--line { width: 100%; height: 40px; justify-content: flex-start; }
.sg-tabbed--pill.sg-tabbed--v .sg-tabbed-list { border-right: 0; padding: 2px; }
.sg-tabbed--pill.sg-tabbed--v .sg-tab { max-width: none; width: 100%; justify-content: flex-start; }

/* pill: the .sg-tab button is inline-block; lay out icon, words and count in a row. The strip scrolls inside a ScrollArea, which needs room for the focus ring */
.sg-tabbed-tab--pill { display: inline-flex; align-items: center; justify-content: center; }
.sg-tabbed--pill .sg-tabbed-list.sg-tabs { overflow: visible; width: max-content; min-width: 100%; padding: 2px; margin: 0; } /* PillTabs' own 4px / −2px room for the ring is not needed here */
.sg-tabbed--pill:not(.sg-tabbed--v) .sg-scrollarea-viewport { padding: 4px; margin: -4px; }
.sg-tabbed--pill .sg-tabbed-label { overflow: hidden; text-overflow: ellipsis; }
/* PillTabs hides the ring of the selected tab (its box-shadow: none comes later); here every tab shows it */
.sg-tabbed--pill .sg-tab:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
/* a count in the selected pill: the pill is light in both themes, so in dark the badge turns dark (PillTabs flips its text the same way, by attribute) */
[data-theme="dark"] .sg-tabbed--pill .sg-tab[aria-selected="true"] .sg-badge.is-ink { --bg: var(--ink-inverse); --fg: var(--ink); }
@media (prefers-color-scheme: dark) {
  /* the same for a page that follows the system theme without data-theme (PillTabs itself only handles the attribute) */
  :root:not([data-theme="light"]) .sg-tabbed--pill .sg-tab[aria-selected="true"] { color: var(--ink-inverse); }
  :root:not([data-theme="light"]) .sg-tabbed--pill .sg-tab[aria-selected="true"] .sg-badge.is-ink { --bg: var(--ink-inverse); --fg: var(--ink); }
}
.sg-tabbed-tab--pill[disabled] { pointer-events: none; }

/* panel: fades in and rises 4px on a change (not on the first paint); no height animation */
.sg-tabbed-panel { min-width: 0; }
.sg-tabbed:not(.sg-tabbed--v) > .sg-tabbed-panel { padding-top: var(--space-4); }
.sg-tabbed-panel.is-anim { animation: sg-tabbed-in var(--duration-quick) var(--ease-liquid) both; }
@keyframes sg-tabbed-in { from { opacity: 0; transform: translateY(4px); } }
@keyframes sg-tabbed-fade { from { opacity: 0; } }
.sg-tabbed-panel[tabindex]:focus-visible { outline: none; border-radius: var(--radius-xs); box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }

@media (forced-colors: active) {
  .sg-tabbed-ind { background: Highlight; forced-color-adjust: none; }
  .sg-tabbed-tab--line[aria-selected="true"] { text-decoration: underline; }
}
@media (prefers-reduced-motion: reduce) {
  /* the indicator jumps, the panel only fades */
  .sg-tabbed-ind, .sg-tabs-ind { transition: none !important; }
  .sg-tabbed-panel.is-anim { animation-name: sg-tabbed-fade; }
}
@media (pointer: coarse) {
  /* 44px targets: the strip clips an extended hit area, so the small size grows instead */
  .sg-tabbed--sm .sg-tabbed-tab--line, .sg-tabbed--v .sg-tabbed-tab--line { height: 44px; }
}

/* ---------- Tag: glass-strong + 1px line, 28 / 24 high, radius-pill. Status carries a StatusLight (shape + colour); selectable rises to solid (recipe C). ---------- */
.sg-tag { --th: 28px; position: relative; display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box; max-width: 100%; height: var(--th); padding: 0 10px; vertical-align: middle;
  border-radius: var(--radius-pill); background: var(--glass-strong); border: 1px solid var(--line); color: var(--ink);
  font: inherit; font-size: 13px; line-height: 18px; font-weight: 500; white-space: nowrap; }
.sg-tag--sm { --th: 24px; gap: 4px; padding: 0 8px; font-size: 12px; line-height: 16px; }
.sg-tag--mono { font-family: var(--font-mono); font-size: 12px; letter-spacing: .02em; }
.sg-tag--sm.sg-tag--mono { font-size: 11px; }
.sg-tag .sg-icon { width: 14px; height: 14px; stroke-width: 1.75; }
.sg-tag--sm .sg-icon { width: 12px; height: 12px; }
.sg-tag-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* the remove button is the IconButton xs ghost, scaled to sit inside the pill */
.sg-tag.has-remove { padding-right: 3px; }
.sg-tag .sg-tag-x.sg-iconbtn--xs { width: 20px; height: 20px; margin: 0; }
.sg-tag--sm .sg-tag-x.sg-iconbtn--xs { width: 18px; height: 18px; }
.sg-tag .sg-tag-x .sg-icon { width: 12px; height: 12px; }
.sg-tag.is-disabled { opacity: var(--disabled); cursor: not-allowed; }

/* selectable: a switch for a filter. Off = quiet glass, on = solid lifted by shadow-lift. */
.sg-tag--select { cursor: pointer; background: var(--glass); color: var(--ink-2); box-shadow: none;
  transition: background-color var(--duration-base) var(--ease-liquid), color var(--duration-base) var(--ease-liquid), border-color var(--duration-base) var(--ease-liquid), box-shadow var(--duration-base) var(--ease-liquid), transform var(--duration-quick) var(--ease-liquid); }
.sg-tag--select:not(:disabled):hover { color: var(--ink); background: var(--glass-strong); }
.sg-tag--select:not(:disabled):active { transform: scale(.96); }
.sg-tag--select.is-on { background: var(--solid); border-color: transparent; box-shadow: var(--shadow-lift); color: var(--ink); color: light-dark(var(--ink), var(--ink-inverse)); }
/* inside a near-white overlay a solid tag cannot be told from an off one: variant="ink" fills with ink instead (recipe C note) */
.sg-tag--select.sg-tag--ink.is-on { background: var(--ink); color: var(--ink-inverse); box-shadow: none; }
.sg-tag--select:disabled { opacity: var(--disabled); cursor: not-allowed; }
/* the lifted shadow of a selected tag has the same specificity as the focus ring and comes later: say it again so the keyboard ring wins */
.sg-tag--select:focus-visible, .sg-tag--select.is-on:focus-visible, .sg-tag--select.sg-tag--ink.is-on:focus-visible { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }

@media (prefers-reduced-motion: reduce) {
  .sg-tag--select { transition-property: background-color, color, border-color, opacity !important; }
  .sg-tag--select:not(:disabled):active { transform: none; }
}
@media (pointer: coarse) {
  /* 28 / 24 high targets get a 44px hit area; the ::after starts at the padding edge, so it reaches 1px further than the maths says.
     Up and down it reaches the full 44px; sideways it stops 2px past the edge, because the gap between two neighbours belongs to neither (a tap in it must not go to the right-hand one, or to a disabled one) */
  .sg-tag--select::after { content: ""; position: absolute; inset: -9px -3px; }
  .sg-tag--sm.sg-tag--select::after { inset: -11px -3px; }
  .sg-tag .sg-tag-x::after { inset: -13px; }
  .sg-tag--sm .sg-tag-x::after { inset: -14px; }
}

/* ---------- TextArea: the recipe-A shell (FieldBox multiline: 10px above and below, 22px lines; 5px and 20px for sm) around a bare <textarea> ---------- */
.sg-ta.sg-field-box { align-items: flex-start; min-width: 0; cursor: text; }
.sg-ta-input { display: block; width: 100%; resize: none; overflow-y: auto; scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--ink) 28%, transparent) transparent; }
.sg-ta-input.is-resizable { resize: vertical; min-height: 1lh; }
.sg-ta-input:disabled { cursor: not-allowed; }
/* 汉字 text needs more air between lines than the 22px / 20px the shared shell sets: 24px (15px type) and 22px (14px type), the system's 中文 body leading (clreq: at least 1.5 times the size).
   The vertical padding gives up 1px (md) / 1px (sm) so that one line still makes the 44px / 32px control height. */
.sg-ta.sg-field-box.sg-field-box--multi:lang(zh) { padding-top: 9px; padding-bottom: 9px; }
.sg-ta.sg-field-box.sg-field-box--multi.sg-field-box--sm:lang(zh) { padding-top: 4px; padding-bottom: 4px; }
.sg-ta.sg-field-box .sg-ta-input:lang(zh) { line-height: 24px; }
.sg-ta.sg-field-box--sm .sg-ta-input:lang(zh) { line-height: 22px; }

@media (prefers-reduced-motion: reduce) {
  /* nothing here moves: the height follows the text without an animation */
}
@media (pointer: coarse) {
  /* the whole shell is the text area (a press on its padding focuses it), so a 32px shell needs nothing beyond the 6px strips the shared shell already adds */
}

/* ---------- Timeline: <ol>; each item is a small grid: [time] [marker rail] [title / words / content] ---------- */
.sg-timeline { --tl-col: 28px; --tl-mark: 24px; --tl-gap: var(--space-5); list-style: none; margin: 0; padding: 0; color: var(--ink); font-size: 15px; line-height: 24px; }
.sg-timeline--sm { --tl-col: 24px; --tl-mark: 20px; --tl-gap: var(--space-4); font-size: 14px; line-height: 20px; }
.sg-timeline-item { display: grid; grid-template-columns: var(--tl-col) minmax(0, 1fr); grid-template-rows: auto auto auto auto var(--tl-gap); grid-template-areas: ". time" "rail title" "rail desc" "rail content" "rail gap"; margin: 0; padding: 0; }
.sg-timeline-item:last-child { --tl-gap: 0px; }
.sg-timeline--aside .sg-timeline-item { grid-template-columns: 120px var(--tl-col) minmax(0, 1fr); grid-template-areas: "time rail title" ". rail desc" ". rail content" ". rail gap"; grid-template-rows: auto auto auto var(--tl-gap); column-gap: 0; }

.sg-timeline-time { grid-area: time; margin: 0; font-family: inherit; font-size: 12px; line-height: 18px; font-weight: 400; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-timeline--aside .sg-timeline-time { align-self: start; padding-top: calc((var(--tl-mark) - 18px) / 2); padding-right: var(--space-3); text-align: right; }
.sg-timeline-title { grid-area: title; min-width: 0; font-weight: 500; color: var(--ink); overflow-wrap: anywhere; }
.sg-timeline-desc { grid-area: desc; min-width: 0; font-size: 13px; line-height: 18px; color: var(--ink-2); overflow-wrap: anywhere; }
.sg-timeline--sm .sg-timeline-desc { font-size: 12px; }
.sg-timeline-content { grid-area: content; min-width: 0; margin-top: var(--space-2); }
.sg-timeline-gap { grid-area: gap; }

/* the rail: a marker the height of the title's first line, then a hairline that fills the rest of the item */
.sg-timeline-rail { grid-area: rail; display: flex; flex-direction: column; align-items: center; min-height: 0; }
.sg-timeline-mark { flex: none; display: grid; place-items: center; width: var(--tl-col); height: var(--tl-mark); }
.sg-timeline-line { flex: 1 1 auto; width: 0; min-height: 8px; margin: -4px 0 calc(var(--tl-next, -4px) - var(--tl-ahead, 0px)); border-left: 1px solid var(--line-strong); }
.sg-timeline-item.has-icon .sg-timeline-line { margin-top: 4px; }
.sg-timeline-item.next-icon { --tl-next: 4px; }
/* stacked: the next item's time sits above its marker, so the hairline reaches down through that row (18px) */
.sg-timeline:not(.sg-timeline--aside) .sg-timeline-item.next-time { --tl-ahead: 18px; }
.sg-timeline-item.is-dashed .sg-timeline-line { border-left-style: dashed; }

.sg-timeline-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ink); }
.sg-timeline-icon { display: grid; place-items: center; box-sizing: border-box; width: var(--tl-mark); height: var(--tl-mark); border-radius: 50%; background: var(--glass); border: 1px solid var(--line); color: var(--ink);
  -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-timeline-icon .sg-icon { width: 14px; height: 14px; }
/* events are over: a state light keeps its shape and colour but does not spin or blink */
.sg-timeline .sg-light { animation: none !important; }
.sg-timeline-busy { color: var(--ink-2); }
.sg-timeline-item.is-pending .sg-timeline-title { font-weight: 400; color: var(--ink-2); }

.sg-timeline-wrap { min-width: 0; }
.sg-timeline-more { margin-top: var(--space-3); margin-left: var(--tl-col, 28px); }
.sg-timeline--sm + .sg-timeline-more { margin-left: 24px; }

/* a new event arrives: fades in 8px low; several arriving together are staggered (at most 7 steps, under 240ms) */
.sg-timeline-item.is-new { animation: sg-timeline-in var(--duration-smooth) var(--ease-liquid) calc(var(--sg-i, 0) * var(--stagger)) both; }
@keyframes sg-timeline-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  @keyframes sg-timeline-in { from { opacity: 0; } to { opacity: 1; } }
}
@media (pointer: coarse) {
  /* nothing here is a tap target except the expand button, which gets the shared 44px hit area */
}

/* ---------- TimePicker: recipe A shell (clock · input · clear · chevron button); the desktop panel is recipe D (radius-md) with hour / minute columns ---------- */
.sg-timepick.sg-field-box { min-width: 0; gap: var(--space-2); padding-right: calc((var(--control-md) - var(--control-xs)) / 2 - 1px); }
.sg-timepick.sg-field-box--sm { padding-right: calc((var(--control-sm) - var(--control-xs)) / 2 - 1px); }
.sg-timepick.is-open { border-color: var(--ink); }
.sg-timepick-input { letter-spacing: .02em; }
.sg-timepick-clear, .sg-timepick-btn { flex: none; }
.sg-timepick-btn .sg-icon { transition: transform var(--duration-quick) var(--ease-liquid); }
.sg-timepick.is-open .sg-timepick-btn .sg-icon { transform: rotate(180deg); }
.sg-timepick-msg.is-solo { margin: 6px 0 0; }
.sg-timepick-msg.sg-field-error { display: flex; align-items: flex-start; gap: 6px; }

/* the panel: 64px columns, 240 high, 4px apart */
.sg-timepick-panel { width: max-content; }
.sg-timepick-cols { display: flex; gap: var(--space-1); }
.sg-timepick-scroll { flex: none; width: 64px; }
.sg-timepick-lb { flex: none; outline: none; border-radius: var(--radius-xs); }
.sg-timepick-list { padding: 4px; gap: 2px; }
.sg-timepick-opt { justify-content: center; min-height: 32px; padding: 4px 0; font-size: 14px; font-variant-numeric: tabular-nums; }
/* the chosen row in a floating panel: ink with ink-inverse text (recipe C written for a near-white surface) */
.sg-timepick-opt[aria-selected="true"], .sg-timepick-opt[aria-selected="true"][data-active] { background: var(--ink); color: var(--ink-inverse); font-weight: 500; }
.sg-timepick-opt[aria-selected="true"]:active { background: var(--ink); }
.sg-timepick-lb:focus-visible .sg-timepick-opt[data-active] { box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); z-index: 1; }
.sg-timepick-foot { display: flex; justify-content: flex-end; margin-top: var(--space-3); padding-top: var(--space-3); border-top: 1px solid var(--line); }
.sg-timepick-foot .sg-btn[aria-disabled="true"] { opacity: var(--disabled); cursor: not-allowed; }

@media (prefers-reduced-motion: reduce) {
  .sg-timepick-opt { transition-property: background-color, color, opacity; }
}
@media (pointer: coarse) {
  /* an xs button is 24px: IconButton's own touch rule reaches 44. Rows grow to 44 with every menu row (_primitives); the 4 + 4px list padding still holds the focus ring. */
  .sg-timepick-scroll { width: 72px; }
}

/* ---------- Toast: recipe D (glass-overlay, blur-lg, line, shadow-float, radius-md). The Toaster is a zero-height anchor at the screen edge; every toast is placed on it by transform, so the stack can fold and unfold on a spring. ---------- */
.sg-toaster { position: fixed; z-index: var(--z-toast); box-sizing: border-box; width: min(420px, calc(100vw - 24px)); height: 0; pointer-events: none; font-family: var(--font-sans); --sg-toast-gap: 8px; }
.sg-toaster[data-y="bottom"] { bottom: calc(var(--sg-toast-offset, 12px) + env(safe-area-inset-bottom, 0px)); --sg-toast-dy: 12px; --sg-toast-oy: 8px; }
.sg-toaster[data-y="top"] { top: calc(var(--sg-toast-offset, 12px) + env(safe-area-inset-top, 0px)); --sg-toast-dy: -12px; --sg-toast-oy: -8px; }
.sg-toaster[data-x="right"] { right: calc(var(--sg-toast-offset, 12px) + env(safe-area-inset-right, 0px)); --sg-toast-ox: 8px; --sg-toast-oy: 0px; }
.sg-toaster[data-x="left"] { left: calc(var(--sg-toast-offset, 12px) + env(safe-area-inset-left, 0px)); --sg-toast-ox: -8px; --sg-toast-oy: 0px; }
.sg-toaster[data-x="center"] { left: 0; right: 0; margin-inline: auto; --sg-toast-ox: 0px; }

.sg-toast-slot { position: absolute; left: 0; right: 0; pointer-events: auto; transform: translateY(var(--sg-toast-y, 0px)) scale(var(--sg-toast-s, 1));
  transition: transform var(--duration-smooth) var(--ease-spring-soft); }
.sg-toaster[data-y="bottom"] .sg-toast-slot { bottom: 0; transform-origin: 50% 100%; }
.sg-toaster[data-y="top"] .sg-toast-slot { top: 0; transform-origin: 50% 0; }
.sg-toast-slot[data-hidden], .sg-toast-slot[data-state="closed"] { pointer-events: none; }
/* unfolded: a bridge across the gap keeps the pointer "inside" while it travels from one toast to the next */
.sg-toaster.is-expanded .sg-toast-slot::before { content: ""; position: absolute; left: 0; right: 0; height: calc(var(--sg-toast-gap) + 2px); }
.sg-toaster[data-y="bottom"].is-expanded .sg-toast-slot::before { bottom: 100%; }
.sg-toaster[data-y="top"].is-expanded .sg-toast-slot::before { top: 100%; }

.sg-toast { position: relative; box-sizing: border-box; display: flex; align-items: center; gap: var(--space-3); width: 100%; min-height: 52px; padding: 12px 12px 12px 16px; border-radius: var(--radius-md); color: var(--ink);
  background: var(--glass-overlay); border: 1px solid var(--line); box-shadow: var(--shadow-float);
  -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4);
  clip-path: inset(-80px round var(--radius-md)); transition: clip-path var(--duration-smooth) var(--ease-spring-soft), opacity var(--duration-base) var(--ease-liquid); }
.sg-toast.has-desc { align-items: flex-start; }
.sg-toast.has-action { padding-top: 10px; padding-bottom: 10px; }
.sg-toast.has-action:not(.has-desc) { padding-top: 9px; padding-bottom: 9px; }   /* 32px button + 18 + 2px border = the 52px minimum, same as a toast without an action */
.sg-toast > * { transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-toast-icon { flex: none; display: grid; place-items: center; width: 20px; height: 20px; color: var(--ink-2); }
.sg-toast.has-desc .sg-toast-icon { margin-top: 4px; }
.sg-toast.is-success .sg-toast-icon { color: var(--status-good); }
.sg-toast.is-warning .sg-toast-icon { color: var(--status-warn); }
.sg-toast.is-error .sg-toast-icon { color: var(--status-bad); }
.sg-toast.is-loading .sg-toast-icon { color: var(--ink); }
.sg-toast-text { flex: 1; min-width: 0; padding-block: 2px; overflow-wrap: anywhere; }
.sg-toast .sg-toast-title { font-weight: 500; color: var(--ink); }
.sg-toast .sg-toast-desc { margin-top: 2px; color: var(--ink-2); }
.sg-toast-action { flex: none; align-self: center; }
.sg-toast-close { flex: none; }
.sg-toast.has-desc .sg-toast-close { align-self: flex-start; margin-top: 2px; }

/* folded: toasts behind the front one are blank glass plates, 12px apart, 5% smaller, clipped to the front toast's height */
.sg-toaster:not(.is-expanded) .sg-toast-slot[data-back] .sg-toast > * { opacity: 0; }
.sg-toaster:not(.is-expanded) .sg-toast-slot[data-back] .sg-toast { clip-path: inset(var(--sg-toast-cut, 0px) 0 0 0 round var(--radius-md)); }
.sg-toaster[data-y="top"]:not(.is-expanded) .sg-toast-slot[data-back] .sg-toast { clip-path: inset(0 0 var(--sg-toast-cut, 0px) 0 round var(--radius-md)); }
.sg-toaster:not(.is-expanded) .sg-toast-slot[data-hidden] .sg-toast { opacity: 0; }

/* Alt+T moves focus by script; browsers do not treat a shortcut chord as keyboard use, so after a mouse click :focus-visible stays off. The Toaster marks that focus itself. */
.sg-toaster[data-kb] .sg-focusable:focus { outline: none; box-shadow: 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }

/* in: 12px from the edge while it fades up out of a 6px blur; out: 8px outward while fading, 2/3 of the time */
.sg-toast.is-enter { animation: sg-toast-in var(--duration-smooth) var(--ease-spring-soft), sg-toast-fade var(--duration-smooth) var(--ease-liquid); }
.sg-toast-slot[data-state="closed"] .sg-toast { animation: sg-toast-out calc(var(--duration-smooth) * 2 / 3) var(--ease-exit) both; pointer-events: none; }
@keyframes sg-toast-in { from { translate: 0 var(--sg-toast-dy, 12px); } }
@keyframes sg-toast-fade { from { opacity: 0; filter: blur(6px); } }
@keyframes sg-toast-out { to { opacity: 0; translate: var(--sg-toast-ox, 0px) var(--sg-toast-oy, 8px); } }
@keyframes sg-toast-fade-out { to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .sg-toast-slot { transition-property: opacity; }
  .sg-toast { transition-property: opacity; }
  .sg-toast.is-enter { animation: sg-toast-fade-only var(--duration-base) var(--ease-liquid); }
  .sg-toast-slot[data-state="closed"] .sg-toast { animation-name: sg-toast-fade-out; }
}
@keyframes sg-toast-fade-only { from { opacity: 0; } }
@media (pointer: coarse) {
  /* the close button (IconButton xs) and the action (Button sm) already carry their own 44px reach from core; the card stays clear of the screen edge */
  .sg-toast-close, .sg-toast-action { position: relative; }
  /* the two reaches (7px around the action, 10px around the close) would overlap across the 12px gap, so a tap just right of "撤销" could dismiss the toast: 6px more air keeps them apart */
  .sg-toast-action + .sg-toast-close { margin-inline-start: 6px; }
}

/* ---------- Tooltip: ink tip (recipe G) — ink fill, ink-inverse text, 12 px, 6 × 10, radius-xs, shadow-lift, 240 max, no arrow, 8 px off the anchor ---------- */
.sg-tooltip-anchor { display: contents; }
.sg-tooltip { position: fixed; box-sizing: border-box; display: flex; align-items: center; gap: var(--space-2); max-width: min(240px, var(--sg-avail-w, 100vw)); margin: 0; padding: 6px 10px;
  border-radius: var(--radius-xs); background: var(--ink); color: var(--ink-inverse); box-shadow: var(--shadow-lift);
  font-family: var(--font-sans); font-size: 12px; line-height: 16px; font-weight: 400; text-align: start; overflow-wrap: anywhere; text-wrap: pretty;
  pointer-events: none; user-select: none; -webkit-user-select: none; transform-origin: var(--sg-origin, 50% 100%); }
.sg-tooltip:lang(zh) { line-height: 18px; }
.sg-tooltip[data-anchor-hidden] { visibility: hidden; }
/* hoverable: the pointer may rest on the tip (WCAG 1.4.13); text can then be selected and copied */
.sg-tooltip[data-hoverable] { pointer-events: auto; user-select: text; -webkit-user-select: text; }
.sg-tooltip-text { min-width: 0; }
.sg-tooltip-keys { flex: none; display: inline-flex; gap: 2px; }
/* keycaps on ink: outline only, drawn from the inverse colour so they flip with the theme */
.sg-tooltip .sg-kbd { height: 18px; min-width: 18px; padding: 0 4px; background: transparent; border-color: color-mix(in srgb, var(--ink-inverse) 32%, transparent); box-shadow: none; color: color-mix(in srgb, var(--ink-inverse) 88%, transparent); }
/* enter: fade + scale .96 + 4 px toward the anchor; exit: 2/3 of the time (keyframes are the overlay ones from the shared primitives) */
.sg-tooltip[data-side="bottom"] { --sg-ov-dx: 0px; --sg-ov-dy: -4px; }
.sg-tooltip[data-side="top"] { --sg-ov-dx: 0px; --sg-ov-dy: 4px; }
.sg-tooltip[data-side="right"] { --sg-ov-dx: -4px; --sg-ov-dy: 0px; }
.sg-tooltip[data-side="left"] { --sg-ov-dx: 4px; --sg-ov-dy: 0px; }
.sg-tooltip[data-state="open"] { animation: sg-ov-in var(--duration-quick) var(--ease-liquid) both; }
.sg-tooltip[data-state="closed"] { animation: sg-ov-out calc(var(--duration-quick) * 2 / 3) var(--ease-exit) both; }
.sg-tooltip[data-instant][data-state="open"] { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .sg-tooltip[data-state="open"] { animation-name: sg-ov-fade; }
  .sg-tooltip[data-state="closed"] { animation-name: sg-ov-fade-out; }
}
/* no tap targets in a tooltip; on touch it only appears for a hardware keyboard, so keep it clear of the screen edge */
@media (pointer: coarse) {
  .sg-tooltip { max-width: min(240px, calc(100vw - 24px)); }
}

/* ---------- Tree: option-row language (recipe E): 36px rows (sm 32), radius-xs, indent per level, twist 14px that turns 90deg ---------- */
.sg-tree { --tr-row: 36px; --tr-pad: 8px; --tr-indent: 20px; list-style: none; margin: 0; padding: 0; min-width: 0; color: var(--ink); font-size: 15px; line-height: 22px; }
.sg-tree--sm { --tr-row: 32px; font-size: 14px; line-height: 20px; }
.sg-tree-item { position: relative; margin: 0; padding: 0; list-style: none; outline: none; }
.sg-tree-row { position: relative; display: flex; align-items: center; gap: 6px; box-sizing: border-box; min-height: var(--tr-row); padding: 0 8px 0 calc(var(--tr-pad) + var(--tr-level, 0) * var(--tr-indent));
  border-radius: var(--radius-xs); cursor: pointer; -webkit-tap-highlight-color: transparent; transition: background-color var(--duration-instant) var(--ease-liquid); }
@media (hover: hover) { .sg-tree-item:not(.is-disabled) > .sg-tree-row:hover { background: var(--state-hover); } }
.sg-tree-item:not(.is-disabled) > .sg-tree-row:active { background: var(--state-pressed); }
.sg-tree-item.is-selected > .sg-tree-row { background: var(--state-selected); font-weight: 500; }
@media (hover: hover) { .sg-tree-item.is-selected:not(.is-disabled) > .sg-tree-row:hover { background: linear-gradient(var(--state-hover), var(--state-hover)), var(--state-selected); } }
.sg-tree-item.is-disabled > .sg-tree-row { opacity: var(--disabled); cursor: not-allowed; }
/* the ring is drawn inward: the tree often sits in a clipped, scrolling panel */
.sg-tree-item:focus-visible > .sg-tree-row { box-shadow: inset 0 0 0 2px var(--focus-ring), inset 0 0 0 4px var(--focus-halo); }

.sg-tree-twist { flex: none; display: grid; place-items: center; width: 14px; height: 14px; color: var(--ink-2); }
.sg-tree-twist .sg-icon { width: 14px; height: 14px; transition: transform calc(var(--duration-base) * 2 / 3) var(--ease-exit); }
.sg-tree-item.is-open > .sg-tree-row .sg-tree-twist .sg-icon { transform: rotate(90deg); transition: transform var(--duration-base) var(--ease-spring-soft); }
.sg-tree-check { flex: none; display: grid; place-items: center; }
.sg-tree-check .sg-check-wrap { display: block; line-height: 0; }
.sg-tree-check .sg-check { display: grid; min-height: 20px; }
.sg-tree-check .sg-check-box { margin-top: 0; }
.sg-tree-check .sg-check-input { top: 0; }
.sg-tree-icon { width: 16px; height: 16px; flex: none; color: var(--ink-2); }
.sg-tree-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-tree-hit { font-weight: 500; color: var(--ink); }
.sg-tree-busy { flex: none; margin-left: auto; color: var(--ink-2); }
.sg-tree-actions { flex: none; display: inline-flex; align-items: center; gap: 2px; margin-left: auto; opacity: 0; transition: opacity var(--duration-quick) var(--ease-liquid); }
.sg-tree-row:hover .sg-tree-actions, .sg-tree-row:focus-within .sg-tree-actions, .sg-tree-item:focus-visible > .sg-tree-row .sg-tree-actions, .sg-tree-item.is-selected > .sg-tree-row .sg-tree-actions { opacity: 1; }

/* children fold with grid-template-rows (0fr to 1fr); closed ones leave the accessibility tree and the tab order after they have finished closing */
.sg-tree-collapse { display: grid; grid-template-rows: 0fr; visibility: hidden;
  transition: grid-template-rows calc(var(--duration-smooth) * 2 / 3) var(--ease-exit), visibility 0s linear calc(var(--duration-smooth) * 2 / 3); }
.sg-tree-item.is-open > .sg-tree-collapse { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows var(--duration-smooth) var(--ease-spring-soft), visibility 0s; }
.sg-tree-group { position: relative; min-height: 0; overflow: hidden; margin: 0; padding: 0; list-style: none; }
/* guides: one hairline per level, under the parent's twist */
.sg-tree--guides .sg-tree-group::before { content: ""; position: absolute; z-index: 1; top: 0; bottom: 0; left: calc(var(--tr-pad) + var(--tr-level, 0) * var(--tr-indent) + 6.5px); width: 1px; background: var(--line); pointer-events: none; }

.sg-tree-item.is-retry > .sg-tree-row { color: var(--ink-2); font-size: 13px; cursor: default; }
.sg-tree-item.is-retry .sg-btn { margin-left: var(--space-1); }
.sg-tree-empty { margin: 0; padding: 0 0 0 calc(var(--tr-pad) + var(--tr-level, 0) * var(--tr-indent) + 20px); list-style: none; }
.sg-tree-empty .sg-empty { padding: 6px 8px 6px 0; }
.sg-tree-empty .sg-empty-title { font-size: 13px; line-height: 18px; font-weight: 400; color: var(--ink-2); }

@media (prefers-reduced-motion: reduce) {
  .sg-tree-collapse, .sg-tree-item.is-open > .sg-tree-collapse { transition: visibility 0s; }
  .sg-tree-twist .sg-icon, .sg-tree-item.is-open > .sg-tree-row .sg-tree-twist .sg-icon { transition: none; }
}
@media (pointer: coarse) {
  /* a finger gets 44px rows, the twist and the checkbox keep their size and reach further, and row actions stay in sight */
  .sg-tree { --tr-row: 44px; }
  .sg-tree-twist::after { content: ""; position: absolute; inset: -14px -8px; }
  .sg-tree-twist { position: relative; }
  .sg-tree-actions { opacity: 1; }
}

/* ---------- WheelPicker: native scrolling columns that snap to rows; a band marks the chosen row; top and bottom fade out ---------- */
.sg-wheel { --sg-wheel-row: 44px; --sg-wheel-rows: 5; position: relative; display: flex; box-sizing: border-box; width: 100%; height: calc(var(--sg-wheel-rows) * var(--sg-wheel-row)); color: var(--ink); font-size: 17px; line-height: 24px; }
.sg-wheel--sm { font-size: 15px; line-height: 20px; }
/* the chosen row: state-selected, 8px in from the sides, behind the numbers */
.sg-wheel-band { position: absolute; z-index: 0; left: var(--space-2); right: var(--space-2); top: calc((var(--sg-wheel-rows) - 1) / 2 * var(--sg-wheel-row)); height: var(--sg-wheel-row);
  border-radius: var(--radius-sm); background: var(--state-selected); pointer-events: none; }
.sg-wheel-col { position: relative; z-index: 1; flex: 1 1 0; min-width: 0; height: 100%; }
.sg-wheel-scroll { height: 100%; box-sizing: border-box; overflow-y: auto; overflow-x: hidden; scroll-snap-type: y mandatory; overscroll-behavior: contain; scrollbar-width: none; outline: none;
  -webkit-overflow-scrolling: touch; -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, black var(--sg-wheel-row), black calc(100% - var(--sg-wheel-row)), transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, black var(--sg-wheel-row), black calc(100% - var(--sg-wheel-row)), transparent 100%); }
.sg-wheel-scroll::-webkit-scrollbar { display: none; }
.sg-wheel--r3 .sg-wheel-scroll { -webkit-mask-image: none; mask-image: none; }
.sg-wheel-pad { flex: none; }
.sg-wheel-item { position: relative; display: flex; align-items: center; justify-content: center; height: var(--sg-wheel-row); scroll-snap-align: center; box-sizing: border-box; padding: 0 var(--space-2);
  color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; cursor: pointer;
  transition: color var(--duration-quick) var(--ease-liquid); }
.sg-wheel-item.is-sel { color: var(--ink); font-weight: 500; }
.sg-wheel-item.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-wheel-lab { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* the unit sits just right of the chosen number, inside the band (zero width, so the number itself stays centred) */
.sg-wheel-sfx { width: 0; margin-left: 4px; overflow: visible; font-size: 15px; font-weight: 400; color: var(--ink-2); opacity: 0; transition: opacity var(--duration-quick) var(--ease-liquid); }
.sg-wheel-item.is-sel .sg-wheel-sfx { opacity: 1; }
.sg-wheel--sm .sg-wheel-sfx { font-size: 13px; }
/* keyboard focus: the ring goes round the chosen row of the focused column (the column itself fades at its ends and would cut it) */
.sg-wheel-col.is-focus::after { content: ""; position: absolute; z-index: 2; left: 4px; right: 4px; top: calc((var(--sg-wheel-rows) - 1) / 2 * var(--sg-wheel-row)); height: var(--sg-wheel-row);
  border-radius: var(--radius-sm); box-shadow: inset 0 0 0 2px var(--focus-halo), inset 0 0 0 4px var(--focus-ring); pointer-events: none; }
.sg-wheel.is-disabled { opacity: var(--disabled); pointer-events: none; }
@media (hover: hover) {
  .sg-wheel-item:not(.is-sel):not(.is-disabled):hover { color: var(--ink); }
}

@media (prefers-reduced-motion: reduce) {
  /* scrolling jumps (the script uses behavior: auto); only colour and opacity are left to ease */
  .sg-wheel-item, .sg-wheel-sfx { transition-property: color, opacity; }
}
@media (pointer: coarse) {
  /* rows are 44 (md) or 36 (sm) high: the small wheel is a reading size, a finger still scrolls anywhere in the column, so nothing needs widening */
  .sg-wheel-scroll { touch-action: pan-y; }
}

/* ---------- Chat kit: ChatThread · ChatMessage (+ ChatToolCall, ChatSources, ChatCitation) · ChatComposer ---------- */
/* thread: the log scrolls, the 回到最新 pill floats over its bottom edge */
.sg-chat { position: relative; display: flex; flex-direction: column; min-height: 0; }
.sg-chat-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; border-radius: var(--radius-sm); }
.sg-chat-scroll:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring), inset 0 0 0 4px var(--focus-halo); }
.sg-chat-inner { display: flex; flex-direction: column; gap: var(--space-5); max-width: 720px; margin: 0 auto; padding: var(--space-4); box-sizing: border-box; }
.sg-chat-latest { position: absolute; left: 50%; bottom: var(--space-3); z-index: 1; opacity: 0; visibility: hidden; pointer-events: none; transform: translate(-50%, 8px);
  transition: opacity calc(var(--duration-quick) * 2 / 3) var(--ease-exit), transform calc(var(--duration-quick) * 2 / 3) var(--ease-exit), visibility 0s linear calc(var(--duration-quick) * 2 / 3); }
.sg-chat-latest[data-show] { opacity: 1; visibility: visible; pointer-events: auto; transform: translate(-50%, 0);
  transition: opacity var(--duration-quick) var(--ease-liquid), transform var(--duration-spring) var(--ease-spring-soft), visibility 0s; }
.sg-chat-latest .sg-btn { box-shadow: var(--shadow-float); }

/* messages */
.sg-chatmsg { display: flex; min-width: 0; color: var(--ink); font-size: 15px; line-height: 24px; }
.sg-chatmsg-body { min-width: 0; overflow-wrap: anywhere; }
.sg-chatmsg-body.is-plain { white-space: pre-wrap; }
.sg-chatmsg-body > :first-child { margin-top: 0; }
.sg-chatmsg-body > :last-child { margin-bottom: 0; }
.sg-chatmsg-body p { margin: 0 0 var(--space-3); }
/* the streaming mark: three breathing dots right after the last token */
.sg-chatmsg-caret { display: inline-flex; vertical-align: middle; margin-left: 6px; color: var(--ink-2); }
/* user: a glass bubble on the right, the corner by the speaker tucked in */
.sg-chatmsg--user { flex-direction: column; align-items: flex-end; gap: var(--space-2); }
.sg-chatmsg-bubble { max-width: min(80%, 560px); box-sizing: border-box; padding: 10px var(--space-4); border-radius: var(--radius-md) var(--radius-md) var(--radius-xs) var(--radius-md);
  background: var(--glass-strong); border: 1px solid var(--line); box-shadow: var(--shadow-glass); -webkit-backdrop-filter: blur(var(--blur-sm)); backdrop-filter: blur(var(--blur-sm)); }
.sg-chatmsg-files { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); max-width: min(80%, 560px); }
.sg-chatmsg-foot { display: flex; align-items: center; gap: var(--space-2); min-height: var(--control-xs); font-size: 12px; line-height: 18px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-chatmsg--user .sg-chatmsg-actions { opacity: 0; transition: opacity calc(var(--duration-base) * 2 / 3) var(--ease-exit); }
.sg-chatmsg--user:hover .sg-chatmsg-actions, .sg-chatmsg--user:focus-within .sg-chatmsg-actions { opacity: 1; transition: opacity var(--duration-base) var(--ease-liquid); }
/* assistant: plain text beside a 28px dot-sphere mark (ThinkingOrb: working while thinking, breathing while streaming, a still globe when done) */
.sg-chatmsg--assistant { gap: var(--space-3); align-items: flex-start; }
.sg-chatmsg-mark { flex: none; width: 28px; height: 28px; display: grid; place-items: center; color: var(--ink); }
.sg-chatmsg-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.sg-chatmsg-head { display: flex; align-items: baseline; gap: var(--space-2); min-height: 28px; align-items: center; font-size: 13px; line-height: 18px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-chatmsg-head b { font-weight: 500; color: var(--ink); }
.sg-chatmsg-head time { font-size: 12px; }
.sg-chatmsg-tools { display: flex; flex-direction: column; gap: var(--space-2); }
.sg-chatmsg-thinking { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--ink-2); }
.sg-chatmsg-error { display: flex; align-items: center; flex-wrap: wrap; gap: var(--space-2); padding: 6px 6px 6px var(--space-3); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--status-bad) 8%, transparent); border: 1px solid color-mix(in srgb, var(--status-bad) 28%, transparent); font-size: 13px; line-height: 20px; }
.sg-chatmsg-error > .sg-icon { width: 16px; height: 16px; color: var(--status-bad); }
.sg-chatmsg-error > span { flex: 1 1 160px; min-width: 0; }
.sg-chatmsg-actions { display: flex; align-items: center; gap: 2px; margin-left: -4px; color: var(--ink-2); }
.sg-chatmsg--user .sg-chatmsg-actions { margin-left: 0; }
.sg-chatmsg-actions .sg-iconbtn { color: var(--ink-2); }
.sg-chatmsg-actions .sg-iconbtn:not([disabled]):hover { color: var(--ink); }
/* system: one centred line between hairlines */
.sg-chatmsg--system { align-items: center; gap: var(--space-3); font-size: 12px; line-height: 18px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-chatmsg--system::before, .sg-chatmsg--system::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.sg-chatmsg-sys { flex: 0 1 auto; max-width: 80%; text-align: center; }

/* attachment chip (composer and user messages) */
.sg-chatfile { display: inline-flex; align-items: center; gap: var(--space-2); max-width: 260px; height: 36px; box-sizing: border-box; padding: 0 4px 0 10px; border-radius: var(--radius-xs);
  background: var(--glass-strong); border: 1px solid var(--line); font-size: 13px; line-height: 18px; color: var(--ink); }
.sg-chatmsg .sg-chatfile { padding-right: 10px; }
.sg-chatfile > .sg-icon { width: 16px; height: 16px; color: var(--ink-2); }
.sg-chatfile-name { display: inline-flex; min-width: 0; white-space: nowrap; }
.sg-chatfile-head { overflow: hidden; text-overflow: ellipsis; }
.sg-chatfile-tail { flex: none; }
.sg-chatfile-meta { flex: none; display: inline-flex; align-items: center; font-size: 12px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-chatfile.is-error { border-color: color-mix(in srgb, var(--status-bad) 40%, transparent); }
/* a failed file keeps its name on the first line; the reason and the fix take the second */
.sg-chatfile.is-error { flex-wrap: wrap; height: auto; min-height: 36px; padding-top: 6px; padding-bottom: 6px; row-gap: 2px; }
.sg-chatfile.is-error .sg-chatfile-name { flex: 1; }
.sg-chatfile.is-error .sg-chatfile-meta { order: 5; flex: 1 0 100%; padding-left: 24px; box-sizing: border-box; color: var(--status-bad); white-space: normal; }

/* tool call: a quiet glass row that folds open (grid-template-rows) to its input and result */
.sg-chattool { border-radius: var(--radius-sm); background: var(--glass); border: 1px solid var(--line); font-size: 13px; line-height: 18px; overflow: hidden; }
.sg-chattool-head { display: flex; align-items: center; gap: var(--space-2); width: 100%; min-height: 36px; box-sizing: border-box; margin: 0; padding: 0 var(--space-3); border: 0; border-radius: inherit; background: transparent;
  font: inherit; color: var(--ink); text-align: left; }
button.sg-chattool-head { cursor: pointer; transition: background-color var(--duration-instant); }
button.sg-chattool-head:hover { background: var(--state-hover); }
button.sg-chattool-head:active { background: var(--state-pressed); }
button.sg-chattool-head:focus-visible { box-shadow: inset 0 0 0 2px var(--focus-ring), inset 0 0 0 4px var(--focus-halo); }
.sg-chattool-mark { flex: none; width: 16px; display: grid; place-items: center; color: var(--ink-2); }
.sg-chattool-mark .sg-icon { width: 16px; height: 16px; }
.sg-chattool.is-done .sg-chattool-mark { color: var(--status-good); }
.sg-chattool.is-error .sg-chattool-mark { color: var(--status-bad); }
.sg-chattool-title { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: var(--space-2); font-weight: 500; white-space: nowrap; }
/* when the row is narrow the function name gives way first, the words last */
.sg-chattool-title > span { flex: 0 1 auto; min-width: 2em; overflow: hidden; text-overflow: ellipsis; }
.sg-chattool-title code { flex: 0 1000 auto; min-width: 0; font-family: var(--font-mono); font-size: 12px; font-weight: 400; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; }
.sg-chattool-meta { flex: none; font-size: 12px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-chattool.is-error .sg-chattool-meta { color: var(--status-bad); }
.sg-chattool-chev, .sg-chatsrc-chev { width: 16px; height: 16px; flex: none; color: var(--ink-2); transition: transform calc(var(--duration-smooth) * 2 / 3) var(--ease-exit); }
.sg-chattool.is-open .sg-chattool-chev, .sg-chatsrc.is-open .sg-chatsrc-chev { transform: rotate(180deg); transition: transform var(--duration-smooth) var(--ease-spring-soft); }
.sg-chattool-panel, .sg-chatsrc-panel { display: grid; grid-template-rows: 0fr; visibility: hidden;
  transition: grid-template-rows calc(var(--duration-smooth) * 2 / 3) var(--ease-exit), visibility 0s linear calc(var(--duration-smooth) * 2 / 3); }
.sg-chattool.is-open > .sg-chattool-panel, .sg-chatsrc.is-open > .sg-chatsrc-panel { grid-template-rows: 1fr; visibility: visible; transition: grid-template-rows var(--duration-smooth) var(--ease-spring-soft), visibility 0s; }
.sg-chattool-in { min-height: 0; overflow: hidden; display: flex; flex-direction: column; gap: var(--space-2); padding: 0 var(--space-3); }
.sg-chattool.is-open .sg-chattool-in { padding-bottom: var(--space-3); }
.sg-chattool-sec { display: flex; flex-direction: column; gap: 4px; }
.sg-chattool-sec > span { font-size: 12px; color: var(--ink-2); }
.sg-chattool-sec.is-error > span { color: var(--status-bad); }
.sg-chattool-sec pre { margin: 0; max-height: 200px; overflow: auto; padding: var(--space-2) var(--space-3); border-radius: var(--radius-xs); background: var(--mist-100);
  font-family: var(--font-mono); font-size: 12px; line-height: 18px; color: var(--ink); white-space: pre-wrap; overflow-wrap: anywhere; }

/* sources: numbered chips, then the list */
.sg-chatsrc { font-size: 13px; line-height: 18px; }
.sg-chatsrc-head { display: inline-flex; align-items: center; gap: var(--space-2); height: var(--control-sm); margin: 0 0 0 -8px; padding: 0 8px; border: 0; border-radius: var(--radius-pill); background: transparent;
  font: inherit; color: var(--ink-2); cursor: pointer; transition: background-color var(--duration-instant), color var(--duration-instant); }
.sg-chatsrc-head:hover { background: var(--state-hover); color: var(--ink); }
.sg-chatsrc-head:active { background: var(--state-pressed); }
.sg-chatsrc-nums { display: inline-flex; }
.sg-chatsrc-nums i, .sg-chatsrc-num, .sg-chatcite { display: inline-grid; place-items: center; box-sizing: border-box; min-width: 18px; height: 18px; padding: 0 4px; border-radius: var(--radius-pill);
  background: var(--glass-strong); border: 1px solid var(--line-strong); font-style: normal; font-size: 11px; line-height: 1; font-weight: 500; color: var(--ink); font-variant-numeric: tabular-nums; }
.sg-chatsrc-nums i + i { margin-left: -4px; }
.sg-chatsrc-list { list-style: none; margin: 0; padding: 0; min-height: 0; overflow: hidden; display: flex; flex-direction: column; }
.sg-chatsrc.is-open .sg-chatsrc-list { padding-top: var(--space-2); }
.sg-chatsrc-list li { display: flex; gap: var(--space-3); padding: var(--space-2) 0; border-top: 1px solid var(--line); }
.sg-chatsrc-num { flex: none; margin-top: 1px; }
.sg-chatsrc-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.sg-chatsrc-title { color: var(--ink); font-weight: 500; text-decoration: none; border-radius: 4px; overflow-wrap: anywhere; }
a.sg-chatsrc-title:hover { text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; }
.sg-chatsrc-site { font-size: 12px; color: var(--ink-2); }
.sg-chatsrc-body p { margin: 2px 0 0; color: var(--ink-2); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* the inline mark sits a little above the baseline, like a footnote */
.sg-chatcite { position: relative; top: -0.35em; margin: 0 1px; vertical-align: baseline; text-decoration: none; cursor: default; }
a.sg-chatcite { cursor: pointer; transition: background-color var(--duration-instant), border-color var(--duration-instant); }
a.sg-chatcite:hover { background: var(--solid); border-color: var(--ink-2); }

/* composer: recipe A on a larger scale — glass-strong shell, line-strong, radius-md; hover ink-2, focus ink + the double ring */
.sg-composer { position: relative; display: flex; flex-direction: column; gap: var(--space-2); box-sizing: border-box; padding: var(--space-3) var(--space-3) var(--space-2); border-radius: var(--radius-md);
  background: var(--glass-strong); border: 1px solid var(--line-strong); box-shadow: var(--shadow-glass); -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md)); cursor: text;
  transition: border-color var(--duration-instant), box-shadow var(--duration-base) var(--ease-liquid); }
.sg-composer:hover { border-color: var(--ink-2); }
.sg-composer:focus-within { border-color: var(--ink); box-shadow: var(--shadow-glass), 0 0 0 2px var(--focus-halo), 0 0 0 4px var(--focus-ring); }
.sg-composer:has(.sg-composer-bar :focus-visible) { box-shadow: var(--shadow-glass); border-color: var(--ink-2); }
.sg-composer.is-drag { border-color: var(--ink); border-style: dashed; }
.sg-composer.is-disabled { opacity: var(--disabled); cursor: not-allowed; }
.sg-composer-files { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.sg-composer-input { display: block; width: 100%; box-sizing: border-box; margin: 0; padding: 0 var(--space-1); border: 0; outline: none; background: transparent; resize: none;
  font: inherit; font-family: var(--font-sans); font-size: 15px; line-height: 24px; color: var(--ink); }
.sg-composer-input::placeholder { color: var(--ink-3); }
.sg-composer-input:disabled { cursor: not-allowed; }
.sg-composer-bar { display: flex; align-items: center; gap: var(--space-2); min-height: var(--control-sm); }
.sg-composer-gap { flex: 1; }
/* a narrow composer (under 480px) drops the key hint first, so the send button never leaves the box */
.sg-composer { container-type: inline-size; }
@container (max-width: 479px) { .sg-composer-hint { display: none; } }
.sg-composer-hint { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; line-height: 18px; color: var(--ink-3); white-space: nowrap; }
/* send: an empty composer shows it as glass (pressing it only focuses the box); with text it turns ink, the one primary of the view; while replying it is the stop button */
.sg-composer-send { flex: none; display: inline-grid; place-items: center; width: var(--control-sm); height: var(--control-sm); padding: 0; border-radius: var(--radius-pill); cursor: pointer;
  background: var(--glass); color: var(--ink-2); border: 1px solid var(--line-strong);
  transition: background-color var(--duration-base) var(--ease-liquid), color var(--duration-base) var(--ease-liquid), border-color var(--duration-base), transform var(--duration-quick) var(--ease-liquid); }
.sg-composer-send .sg-icon { width: 16px; height: 16px; stroke-width: 2; }
.sg-composer-send.is-ready, .sg-composer-send.is-stop { background: var(--ink); color: var(--ink-inverse); border-color: var(--ink); box-shadow: var(--shadow-lift); }
.sg-composer-send.is-stop .sg-icon { width: 12px; height: 12px; fill: currentColor; stroke-width: 1.5; }
.sg-composer-send:active { transform: scale(.92); }
.sg-composer-send[disabled] { cursor: not-allowed; transform: none; }
.sg-composer-drop { position: absolute; inset: 4px; z-index: 1; display: flex; align-items: center; justify-content: center; gap: var(--space-2); border-radius: calc(var(--radius-md) - 4px);
  background: var(--glass-overlay); font-size: 13px; font-weight: 500; color: var(--ink); pointer-events: none; }
.sg-composer-drop .sg-icon { width: 18px; height: 18px; }

@media (prefers-reduced-motion: reduce) {
  .sg-chat-latest, .sg-chat-latest[data-show] { transform: translate(-50%, 0); transition-property: opacity, visibility; }
  .sg-chattool-panel, .sg-chatsrc-panel, .sg-chattool.is-open > .sg-chattool-panel, .sg-chatsrc.is-open > .sg-chatsrc-panel { transition: visibility 0s; }
  .sg-chattool-chev, .sg-chatsrc-chev, .sg-chattool.is-open .sg-chattool-chev, .sg-chatsrc.is-open .sg-chatsrc-chev { transition: none; }
  .sg-composer-send:active { transform: none; }
  .sg-chatmsg-caret .sg-busy i { animation: none; opacity: .6; }
}
@media (pointer: coarse) {
  /* phones: the actions stay visible (there is no hover), the hint about keys goes away, and the small targets grow to 44px without changing their look */
  .sg-chatmsg--user .sg-chatmsg-actions { opacity: 1; }
  .sg-composer-hint { display: none; }
  .sg-composer-send, .sg-chatsrc-head, a.sg-chatcite { position: relative; }
  .sg-composer-send::after, .sg-chatsrc-head::after { content: ""; position: absolute; inset: -6px; }
  a.sg-chatcite::after { content: ""; position: absolute; inset: -13px; }
  .sg-chattool-head { min-height: 44px; }
}

/* ---------- LineChart (shares the data-colour variables and .sg-ch--nebula with BarChart) ---------- */
.sg-lines { position: relative; display: block; width: 100%; box-sizing: border-box; color: var(--sg-ch-ink); border-radius: var(--radius-xs); font-family: var(--font-sans);
  --sg-ch-ring: var(--mist-000); }
.sg-lines.sg-ch--nebula { --sg-ch-ring: var(--nebula-deep); }
.sg-lines.is-loading { opacity: .5; transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-lines-plot { position: relative; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
.sg-lines-svg { display: block; overflow: visible; }
.sg-lines-svg text { font-family: var(--font-sans); font-size: 12px; font-weight: 400; font-variant-numeric: tabular-nums; fill: var(--sg-ch-ink-2); transition: fill var(--duration-base) var(--ease-liquid); }
.sg-lines-svg text.is-cur { fill: var(--sg-ch-ink); font-weight: 500; }
.sg-lines-grid { stroke: var(--sg-ch-line); stroke-width: 1; stroke-dasharray: 2 4; fill: none; }
.sg-lines-base { stroke: var(--sg-ch-line); stroke-width: 1; fill: none; }
.sg-lines-series { transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-lines-series.is-dim { opacity: .24; }
.sg-lines-line { fill: none; stroke: var(--c); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.sg-lines--one .sg-lines-line { stroke-width: 1.75; }
.sg-lines-series.is-cur .sg-lines-line { stroke-width: 2.5; }
.sg-lines-lone { fill: var(--c); }
.sg-lines-cross { stroke: var(--sg-ch-ink); stroke-opacity: .32; stroke-width: 1; transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-lines-dots circle { fill: var(--c); stroke: var(--sg-ch-ring); stroke-width: 2; transition: opacity var(--duration-base) var(--ease-liquid); }
.sg-lines-dots circle.is-dim { opacity: .24; }
/* data change: each line draws in from the left (series 40ms apart); its area fades in under it — never on the first render */
@keyframes sg-lines-draw { from { clip-path: inset(-10% 100% -10% 0); } to { clip-path: inset(-10% 0 -10% 0); } }
@keyframes sg-lines-fade { from { opacity: 0; } }
.sg-lines-line.is-draw { animation: sg-lines-draw var(--duration-slow) var(--ease-liquid) backwards; animation-delay: var(--d, 0ms); }
.sg-lines-area.is-fade { animation: sg-lines-fade var(--duration-slow) var(--ease-liquid) backwards; animation-delay: var(--d, 0ms); }
/* the readout: the glass of the BarChart pill, a few rows tall, sliding beside the crosshair */
.sg-lines-tip { position: absolute; left: 0; top: 0; z-index: 1; pointer-events: none; display: flex; flex-direction: column; gap: 4px; box-sizing: border-box; padding: 8px 12px; border-radius: var(--radius-sm);
  background: var(--glass-overlay); border: 1px solid var(--line); box-shadow: var(--shadow-glass); -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4);
  font-size: 12px; line-height: 16px; color: var(--sg-ch-ink); font-variant-numeric: tabular-nums; white-space: nowrap; transition: transform var(--duration-spring) var(--ease-spring-soft); }
.sg-lines-tip-cat { color: var(--sg-ch-ink-2); }
.sg-lines-tip-row { display: flex; align-items: center; gap: 6px; transition: opacity var(--duration-base); }
.sg-lines-tip-row.is-dim { opacity: .4; }
.sg-lines-tip-row i { width: 8px; height: 8px; border-radius: 50%; background: var(--c); flex: none; }
.sg-lines-tip-row span { flex: 1; color: var(--sg-ch-ink-2); padding-right: var(--space-3); }
.sg-lines-tip-row b { font-weight: 500; margin-left: auto; }
.sg-ch--nebula .sg-lines-tip { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.4); box-shadow: none; }
/* legend: a short stroke of the series colour, so it reads as a line, not a bar */
.sg-lines-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 12px 0 0; padding: 0; list-style: none; font-size: 12px; line-height: 18px; color: var(--sg-ch-ink-2); }
.sg-lines-legend li { display: inline-flex; align-items: center; gap: 6px; transition: color var(--duration-instant); }
.sg-lines-legend li.is-cur { color: var(--sg-ch-ink); }
.sg-lines-legend i { width: 14px; height: 3px; border-radius: var(--radius-pill); background: var(--c); flex: none; }
.sg-lines-skel { display: block; width: 100%; height: calc(100% - 28px); padding-top: 12px; box-sizing: border-box; overflow: visible; }
.sg-lines-skel path { fill: none; stroke: var(--skeleton); stroke-width: 3; stroke-linecap: round; animation: sg-lines-pulse var(--duration-loop) var(--ease-in-out) infinite alternate; }
@keyframes sg-lines-pulse { to { opacity: .45; } }

@media (prefers-reduced-motion: reduce) {
  .sg-lines-tip, .sg-lines-cross { transition-property: opacity !important; }
  .sg-lines-line.is-draw { animation-name: sg-lines-fade !important; animation-duration: var(--duration-base) !important; animation-delay: 0ms !important; }
  .sg-lines-area.is-fade { animation-duration: var(--duration-base) !important; animation-delay: 0ms !important; }
  .sg-lines-skel path { animation: none; }
}
@media (pointer: coarse) {
  /* the whole plot is the target: the finger picks the nearest point by its x position */
  .sg-lines-plot { min-height: 44px; }
}

/* ---------- SortableList: rows that slide aside on a soft spring while one is lifted as overlay glass ---------- */
.sg-sort { --sl-row: var(--row-md); color: var(--ink); font-size: 15px; line-height: 22px; }
.sg-sort--sm { --sl-row: var(--row-sm); font-size: 14px; line-height: 20px; }
.sg-sort--surface { border-radius: var(--radius-md); background: var(--glass); border: 1px solid var(--line); box-shadow: var(--shadow-glass); -webkit-backdrop-filter: blur(var(--blur-md)); backdrop-filter: blur(var(--blur-md)); padding: 4px; }
.sg-sort-list { position: relative; list-style: none; margin: 0; padding: 0; }
.sg-sort-item { position: relative; display: flex; align-items: center; gap: var(--space-2); min-height: var(--sl-row); box-sizing: border-box; padding: 4px var(--space-3) 4px 4px; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: transparent; translate: 0 var(--sl-y, 0px);
  transition: translate var(--duration-spring) var(--ease-spring-soft), scale var(--duration-quick) var(--ease-liquid), box-shadow var(--duration-base) var(--ease-liquid), background-color var(--duration-instant); }
/* the hairline between rows starts at the text, like List */
.sg-sort-item + .sg-sort-item::before { content: ""; position: absolute; top: -1px; left: 44px; right: var(--space-3); height: 1px; background: var(--line); transition: opacity var(--duration-instant); }
.sg-sort.is-dragging .sg-sort-item::before { opacity: 0; }
.sg-sort.is-dragging, .sg-sort.is-dragging * { cursor: grabbing; -webkit-user-select: none; user-select: none; }
.sg-sort-item.is-lifted { z-index: 2; scale: 1.02; background: var(--glass-overlay); border-color: var(--line); box-shadow: var(--shadow-float); -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.4); backdrop-filter: blur(var(--blur-lg)) saturate(1.4); }
.sg-sort-item.is-follow { transition: scale var(--duration-quick) var(--ease-liquid), box-shadow var(--duration-base) var(--ease-liquid); }
.sg-sort-item.is-drop { z-index: 2; }
/* the frame of a drop: every row snaps to its new place with no transition; the next frame the dropped row slides home */
.sg-sort.is-settling .sg-sort-item { transition: none; }
.sg-sort-handle { flex: none; display: inline-grid; place-items: center; width: var(--control-sm); height: var(--control-sm); margin: 0; padding: 0; border: 0; border-radius: var(--radius-xs); background: transparent;
  color: var(--ink-3); cursor: grab; touch-action: none; transition: background-color var(--duration-instant), color var(--duration-instant); }
.sg-sort-handle .sg-icon { width: 18px; height: 18px; }
.sg-sort-handle:not(:disabled):hover { background: var(--state-hover); color: var(--ink); }
.sg-sort-handle:not(:disabled):active, .sg-sort-handle[aria-pressed="true"] { background: var(--state-pressed); color: var(--ink); cursor: grabbing; }
.sg-sort-handle:disabled { cursor: not-allowed; }
.sg-sort.is-disabled .sg-sort-list { opacity: var(--disabled); }
.sg-sort-body { flex: 1; min-width: 0; display: flex; align-items: center; gap: var(--space-3); }
.sg-sort-icon { flex: none; width: 32px; height: 32px; display: grid; place-items: center; border-radius: 50%; background: var(--glass-strong); border: 1px solid var(--line); color: var(--ink-2); }
.sg-sort-icon .sg-icon { width: 16px; height: 16px; }
.sg-sort-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.sg-sort-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-sort-desc { font-size: 13px; line-height: 18px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sg-sort-meta { flex: none; font-size: 13px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sg-sort-index { flex: none; min-width: 20px; text-align: right; font-size: 12px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

@media (prefers-reduced-motion: reduce) {
  .sg-sort-item { transition: box-shadow var(--duration-base) linear, background-color var(--duration-instant); }
  .sg-sort-item.is-lifted { scale: none; }
}
@media (pointer: coarse) {
  .sg-sort-handle { position: relative; }
  .sg-sort-handle::after { content: ""; position: absolute; inset: -6px; }
}
