
/* Bridge components. Every colour, corner radius, blur and time comes from a token (tokens.css, made from
   tokens.json): a --br-* custom property, so a theme reaches all of it. kit/theme/lint.mjs fails the build on a raw one. */
* { box-sizing: border-box; }
/* A change of theme (Kit's theme runtime): the old look fades into the new one as a whole. */
html.br-theme-fade::view-transition-old(root), html.br-theme-fade::view-transition-new(root) { animation-duration: var(--br-motion-theme); animation-timing-function: var(--br-motion-ease-standard); }
html, body { margin: 0; }
body { background: var(--br-wallpaper-base); color: var(--br-text-primary); font-family: var(--br-font-ui); font-size: 14px; line-height: 20px; -webkit-font-smoothing: antialiased; }
/* Highlighted, on anything that can be chosen (decision 149): under the pointer or with the keyboard's focus it gets
   the highlight edge alone (no fill, no glow inside; decision 151), the same as the D-pad's highlight (.is-pad-focus). What's selected,
   open, switched on or the current page keeps its own look. Kept light (two classes' weight) and early, so a part's own
   hover (buttons, tiles, covers) still wins and only parts with none get this. */
:where(button, a[href], summary, [role=button], [role=tab], [role=option], [role=switch], [role=radio], [role=menuitem], [role=menuitemradio], [role=menuitemcheckbox], [data-click]):not(.is-selected, .is-open, [aria-selected="true"], [aria-checked="true"], [aria-current="page"], [disabled], .primary):is(:hover, :focus-visible) {
  box-shadow: var(--br-highlight-edge); }

/* A stand-in live wallpaper for previews: the app draws real wallpapers. */
.b-wall {
  position: relative; min-height: 100%; padding: var(--br-space-5);
  background:
    radial-gradient(60% 80% at 15% 20%, color-mix(in srgb, var(--br-accent-primary) 55%, transparent), transparent 70%),
    radial-gradient(55% 75% at 85% 75%, color-mix(in srgb, var(--br-accent-secondary) 70%, transparent), transparent 70%),
    radial-gradient(40% 50% at 60% 10%, var(--br-preview-wall-warm), transparent 70%),
    var(--br-wallpaper-base);
}
.b-wall.busy::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(115deg, var(--br-tint-10) 0 2px, transparent 2px 18px); }
.b-wall > * { position: relative; z-index: 1; }
.b-row { display: flex; gap: var(--br-space-2); align-items: center; flex-wrap: wrap; }
.b-col { display: flex; flex-direction: column; gap: var(--br-space-2); }

/* <small> is 12px everywhere (the browser's own "smaller" lands between sizes on the type scale). */
.b-app small { font-size: 12px; }

/* THE glass. One look for every surface. */
.b-glass {
  background: var(--br-glass-tint);
  -webkit-backdrop-filter: blur(var(--br-glass-blur)) saturate(var(--br-glass-saturation));
  backdrop-filter: blur(var(--br-glass-blur)) saturate(var(--br-glass-saturation));
  border: 1px solid var(--br-glass-edge);
  box-shadow: var(--br-shadow-edge-light), var(--br-shadow-glass);
  border-radius: var(--br-shape-radius);
}
.b-inset { background: var(--br-glass-inset); border-radius: var(--br-shape-radius); }

/* Labels */
.b-label { font-family: var(--br-font-display); font-size: 11px; line-height: 16px; font-weight: 600; letter-spacing: 0.8px; text-transform: uppercase; color: var(--br-text-secondary); }
.b-muted { color: var(--br-text-secondary); }
.b-num { font-family: var(--br-font-mono); font-variant-numeric: tabular-nums; font-size: 13px; font-weight: 500; }

/* Buttons */
.b-btn {
  height: var(--br-size-control); padding: 0 var(--br-space-4); display: inline-flex; align-items: center; gap: var(--br-space-2);
  border-radius: var(--br-shape-radius); border: 0;   /* the edge is the inset line below: a border left a gap between it and a highlight's edge (a double outline) */
  background: var(--br-glass-tint); -webkit-backdrop-filter: blur(var(--br-glass-blur)) saturate(var(--br-glass-saturation)); backdrop-filter: blur(var(--br-glass-blur)) saturate(var(--br-glass-saturation));
  box-shadow: inset 0 0 0 1px var(--br-glass-edge), var(--br-shadow-edge-light);
  color: var(--br-text-primary); font: 600 14px/20px var(--br-font-ui); cursor: pointer;
  transition: transform var(--br-motion-press) var(--br-motion-ease-standard), background-color var(--br-motion-press) var(--br-motion-ease-standard);
}
.b-btn:hover, .b-btn.is-focus, .b-btn.is-pad-focus { background-color: color-mix(in srgb, var(--br-glass-tint) 100%, transparent); box-shadow: var(--br-highlight-edge); }
.b-btn:active, .b-btn.is-pressed { transform: scale(0.97); box-shadow: var(--br-shadow-edge-light), inset 0 0 0 999px var(--br-glass-lift-strong); }
.b-btn.primary { background: var(--br-accent-primary); color: var(--br-text-on-accent); border-color: transparent;
  box-shadow: 0 4px 12px color-mix(in srgb, var(--br-accent-primary) 40%, transparent), inset 0 1px 0 var(--br-tint-32); }
/* Icons on an accent button always use the button's own text colour, even inside rows or menus that tint icons. */
.b-btn.primary .b-icon, .b-item .b-btn.primary .b-icon { color: var(--br-text-on-accent); }
.b-btn.console { height: var(--br-size-control-lg); padding: 0 var(--br-space-6); font: 600 18px/20px var(--br-font-display); }
/* Play (the big accent button) gives off a soft glow in its own colour. */
.b-btn.primary.console { box-shadow: 0 0 22px color-mix(in srgb, var(--br-accent-primary) 45%, transparent), 0 6px 20px color-mix(in srgb, var(--br-accent-secondary) 30%, transparent); }
.b-btn.quiet { background: transparent; border-color: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.b-btn.quiet:hover, .b-btn.quiet.is-focus, .b-btn.quiet.is-pad-focus { box-shadow: var(--br-highlight-edge); }
.b-btn.danger { color: var(--br-state-danger); }
/* A menu row that destroys something (Remove web app): the danger colour for its icon and words. */
.b-item.danger { color: var(--br-state-danger); }
.b-btn.sm { height: var(--br-size-control-sm); padding: 0 var(--br-space-3); border-radius: var(--br-shape-radius); font-size: 13px; }
/* Disabled looks disabled and never reacts: no hover light, no press, half strength (primary buttons included). */
.b-btn[disabled] { color: var(--br-text-secondary); cursor: default; opacity: 0.55; pointer-events: none; box-shadow: inset 0 0 0 1px var(--br-glass-edge), var(--br-shadow-edge-light); }   /* still readable: you can see what it is */
.b-btn.primary[disabled] { color: var(--br-text-on-accent); }
.b-btn.quiet[disabled] { box-shadow: none; }   /* a quiet button has no edge, disabled or not (Files' Forward) */
.b-field:has(input:disabled) { opacity: 0.5; }
.b-icon-btn { width: var(--br-size-control); padding: 0; justify-content: center; }
/* Standard buttons: text always centred, and no text button narrower than 96px, so short labels never make odd little buttons. */
.b-btn { justify-content: center; }
.b-btn:not(.b-icon-btn) { min-width: 96px; }
/* A group of actions is a grid of equal-width buttons, never a ragged row sized by label length (as in Apple's panels).
   Two columns by default; .wide spans the full row (put the main action first and wide). */
.b-actions { display: grid; grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr)); gap: var(--br-space-2); }
.b-actions > .wide { grid-column: 1 / -1; }
.b-actions > .b-btn { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Dialog buttons are all the same width too. */
.b-icon-btn.sm { width: var(--br-size-control-sm); }
.b-icon { width: var(--br-size-icon); height: var(--br-size-icon); stroke: currentColor; fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; flex: none; }
/* Icon packs (Bridge Themes): the same named icons in another hand. filled: the shape filled in softly; pixel: square
   ends and corners, on whole pixels; glyph: a character in the mono font (Kit's Icon writes it). */
:root[data-br-icons="filled"] svg.b-icon { fill: currentColor; fill-opacity: 0.24; stroke-width: 2; }
:root[data-br-icons="pixel"] svg.b-icon { stroke-linecap: square; stroke-linejoin: miter; shape-rendering: crispEdges; stroke-width: 2; }
.b-glyph { display: inline-grid; place-items: center; stroke: none; font: 600 15px/1 var(--br-font-mono); text-align: center; }

/* Fields */
.b-field {
  height: var(--br-size-control); display: flex; align-items: center; gap: var(--br-space-2); padding: 0 var(--br-space-3);
  border-radius: var(--br-shape-radius); background: var(--br-glass-inset); border: 1px solid var(--br-glass-edge); color: var(--br-text-primary);
}
.b-field.on-wall { background: var(--br-glass-tint); -webkit-backdrop-filter: blur(var(--br-glass-blur)) saturate(var(--br-glass-saturation)); backdrop-filter: blur(var(--br-glass-blur)) saturate(var(--br-glass-saturation)); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-glass); }
.b-field.hero { height: var(--br-size-hero-search); padding: 0 var(--br-space-4); font-size: 18px; }
.b-field input { flex: 1; min-width: 0; background: none; border: 0; outline: 0; color: var(--br-text-primary); font: inherit; }
/* A search bar (any field) is highlighted as a whole, around its edge, never the text box inside it (decision 152):
   under the pointer, or when the D-pad is on it. */
.b-field input.is-pad-focus { background: none !important; box-shadow: none !important; }
.b-field input::placeholder { color: var(--br-text-primary); opacity: 0.9; }   /* white, like the rest of the bar's text */
/* No Windows UI in fields: Edge's own password reveal and clear buttons are hidden (Bridge's eye and × take their place). */
.b-app input::-ms-reveal, .b-app input::-ms-clear { display: none; }
.b-field .b-field-clear.is-open { color: var(--br-accent-primary); }
.b-field .b-icon { color: var(--br-text-secondary); }

/* Chips and segmented switch */
.b-chip { height: var(--br-size-control-sm); padding: 0 var(--br-space-3); display: inline-flex; align-items: center; gap: var(--br-space-1);
  border-radius: var(--br-shape-radius); background: var(--br-glass-inset); color: var(--br-text-secondary); font: 600 13px/18px var(--br-font-ui); box-shadow: 0 1px 4px var(--br-shade-12);
  transition: transform var(--br-motion-move) var(--br-motion-ease-standard), background-color var(--br-motion-move) var(--br-motion-ease-standard), color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-chip.is-selected { color: var(--br-text-primary); background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); transform: scale(var(--br-motion-select-scale)); }
/* Segmented switch: the selected option fills the housing edge to edge (same 16px corners, no inset) in the
   --br-selected-fill switch highlight. In the app it is one highlight that slides between options (150ms, standard curve), the way the
   Electron Bridge's tabs, Settings list and Games filters did. */
/* Every switch housing has the same glassy edge as a search field: a 1px glass edge and the top light. */
.b-seg.b-inset { border: 1px solid var(--br-glass-edge); box-shadow: var(--br-shadow-edge-light); }
/* Every option in a switch is the same width (as wide as the longest label), so the highlight is one size as it slides. */
.b-seg { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr; padding: 0; gap: 0; border-radius: var(--br-shape-radius); }
.b-seg > span { height: calc(var(--br-size-control) - 2px); padding: 0 var(--br-space-4); display: inline-flex; align-items: center; justify-content: center; border-radius: var(--br-shape-radius);
  font: 500 13px/18px var(--br-font-display); color: var(--br-text-secondary);
  transition: background-color var(--br-motion-move) var(--br-motion-ease-standard), color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-seg > span.is-selected { color: var(--br-text-primary); background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }

/* Toggle */
/* A switch (decision 148): its edge is an inset line, not a border, so the on look's neon edge has no gap in it. On, it
   looks like a slider's fill: the selected look (the neon edge with the glow inside) with the slider's white knob. */
.b-toggle { width: 46px; height: 28px; border-radius: var(--br-shape-pill); background: var(--br-glass-inset); border: 0; box-shadow: inset 0 0 0 1px var(--br-glass-edge); position: relative; flex: none;
  transition: background-color var(--br-motion-move) var(--br-motion-ease-standard), box-shadow var(--br-motion-move) var(--br-motion-ease-standard); }
.b-toggle::after { content: ""; position: absolute; top: 4px; left: 4px; width: 20px; height: 20px; border-radius: var(--br-shape-pill); background: var(--br-text-secondary); transition: transform var(--br-motion-move) var(--br-motion-ease-standard), background-color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-toggle.on { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }
.b-toggle.on::after { transform: translateX(18px); background: var(--br-tint-100); box-shadow: 0 1px 4px var(--br-shade-30), 0 0 0 0.5px var(--br-shade-10); }   /* the slider thumb's white and shadow */

/* Slider and progress */
.b-track { height: 6px; border-radius: var(--br-shape-pill); background: var(--br-glass-inset); position: relative; flex: 1 1 auto; align-self: center; min-width: 40px; }
.b-col > .b-track, .b-track.bar { flex: none; height: 4px; align-self: stretch; }
.b-track > i { position: absolute; inset: 0 auto 0 0; border-radius: inherit; background: var(--br-accent-primary); }
/* A slider's filled part wears the selected look (FIXES #108), like a selected tab: the accent-tinted glass with its
   thin accent edge, not a solid colour. The track is a little taller so the edge shows. Thin bars (progress, levels)
   keep the solid fill. */
.b-track[role="slider"] { height: 10px; }
.b-track[role="slider"] > i { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); min-width: 10px; }
.b-track > b { position: absolute; top: 50%; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: var(--br-shape-pill); background: var(--br-tint-100); box-shadow: 0 1px 4px var(--br-shade-30), 0 0 0 0.5px var(--br-shade-10); }

/* Top bar */
.b-topbar { height: var(--br-size-control-lg); display: grid; grid-template-columns: 1fr auto 1fr; column-gap: var(--br-space-4); align-items: center; padding: 0 var(--br-space-2); }   /* the gap: a wide now playing never touches the tabs */
.b-topbar .left, .b-topbar .right { display: flex; align-items: center; gap: var(--br-space-1); }
.b-topbar .right { justify-content: flex-end; }
/* Top bar tabs are all the same width (as wide as the longest tab name), like switch options. */
.b-tabs { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: var(--br-space-1); }
.b-tab { height: max(32px, calc(var(--br-size-control) - 4px)); padding: 0 var(--br-space-4); display: inline-flex; align-items: center; justify-content: center; border-radius: var(--br-shape-radius);
  font: 500 14px/20px var(--br-font-display); color: var(--br-text-primary); text-decoration: none;   /* white in the top bar, selected or not */
  transition: transform var(--br-motion-move) var(--br-motion-ease-standard), color var(--br-motion-move) var(--br-motion-ease-standard), background-color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-tab:hover { color: var(--br-text-primary); box-shadow: var(--br-highlight-edge); }
.b-tab.is-selected { color: var(--br-text-primary); background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); transform: scale(var(--br-motion-select-scale)); }
.b-status { height: max(32px, calc(var(--br-size-control) - 4px)); padding: 0 var(--br-space-2); display: inline-flex; align-items: center; gap: var(--br-space-2); border-radius: var(--br-shape-radius); color: var(--br-text-primary); }
.b-status:hover { box-shadow: var(--br-highlight-edge); }
.b-logo { height: max(32px, calc(var(--br-size-control) - 4px)); padding: 0 var(--br-space-3) 0 var(--br-space-2); display: inline-flex; align-items: center; gap: var(--br-space-2); border-radius: var(--br-shape-radius); color: var(--br-text-primary); text-decoration: none; font: 400 16px/20px var(--br-font-wordmark); letter-spacing: 1.6px; text-transform: uppercase; }
/* The mark is the accent, with a soft shadow to stand out; on Home (the logo selected, on the accent tint) it
   turns white so it still shows. */
.b-logo svg { width: 30px; height: 21px; flex: none; filter: drop-shadow(0 1px 3px var(--br-shade-45)); }
.b-logo.is-selected { --logo: var(--br-tint-100); }
.b-logo:hover { box-shadow: var(--br-highlight-edge); }
.b-logo.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); transform: scale(var(--br-motion-select-scale)); }
a { color: inherit; }

/* Menus, list rows */
.b-menu { padding: var(--br-space-2); min-width: 220px; display: flex; flex-direction: column; gap: 2px; box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.b-item { flex: none; height: var(--br-size-control); padding: 0 var(--br-space-3); display: flex; align-items: center; gap: var(--br-space-3); border-radius: var(--br-shape-radius); color: var(--br-text-primary);
  transition: transform var(--br-motion-move) var(--br-motion-ease-standard), background-color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-item .b-icon { color: var(--br-text-secondary); }
.b-item .end { margin-left: auto; color: var(--br-text-secondary); }
.b-item.is-focus { box-shadow: var(--br-highlight-edge); }
/* Selected rows look exactly like the top bar's selected tab: the accent-tinted glass with its thin accent edge
   (one selected look everywhere, no solid fill). A highlighted row has the edge alone: no fill, no glow inside. */
.b-item.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); transform: scale(1.02); }
.b-divider { height: 1px; margin: var(--br-space-1) var(--br-space-2); background: var(--br-glass-edge); }

/* Toast */
/* Every bottom popup (toasts, undo, the Files selection bar) is one size: 560 x 52, centred 24px above the bottom. */
.b-toast { width: 560px; max-width: calc(100% - 32px); height: 52px; flex: none; padding: 0 var(--br-space-2) 0 var(--br-space-4); display: flex; align-items: center; gap: var(--br-space-3); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.b-toast .dot { width: 8px; height: 8px; border-radius: var(--br-shape-pill); flex: none; }

/* Tiles: game covers, wallpapers, Overview cards */
.b-tile { border-radius: var(--br-shape-radius); overflow: hidden; box-shadow: var(--br-shadow-tile); flex: none;
  transition: transform var(--br-motion-move) var(--br-motion-ease-standard), box-shadow var(--br-motion-move) var(--br-motion-ease-standard); }
/* Pointing at a tile with the mouse is the same as moving the highlight to it: it grows in place. */
.b-tile.is-selected { transform: scale(var(--br-motion-tile-scale)); box-shadow: var(--br-shadow-lift); }
.b-tile:hover, .b-tile.is-hover { transform: scale(var(--br-motion-tile-scale)); box-shadow: var(--br-highlight-edge), var(--br-shadow-lift); }
/* Grid covers: on mouse hover only (a controller just moves the highlight as usual: A plays, Y opens the menu), Play, Details and Favorite fade up over the bottom of the cover and the name rises above them. */
.b-cover .hover-actions { position: absolute; left: 10px; right: 10px; bottom: 10px; display: flex; gap: 6px; opacity: 0; transform: translateY(6px);
  transition: opacity var(--br-motion-move) var(--br-motion-ease-standard), transform var(--br-motion-move) var(--br-motion-ease-standard); }
.b-cover .hover-actions .b-btn { width: 36px; height: 36px; }
.b-cover .hover-actions .b-btn.primary { flex: 1; }
.b-cover:has(.hover-actions)::after { content: ""; position: absolute; inset: 40% 0 0 0; border-radius: inherit; pointer-events: none; opacity: 0;
  background: linear-gradient(180deg, transparent, var(--br-deep-75)); transition: opacity var(--br-motion-move) var(--br-motion-ease-standard); }
.b-cover:has(.hover-actions) > span:not(.b-badge) { transition: transform var(--br-motion-move) var(--br-motion-ease-standard); z-index: 1; }
.b-cover.is-hover .hover-actions, .b-cover:hover .hover-actions { opacity: 1; transform: none; z-index: 2; }
.b-cover.is-hover:has(.hover-actions)::after, .b-cover:hover:has(.hover-actions)::after { opacity: 1; }
.b-cover.is-hover:has(.hover-actions) > span:not(.b-badge), .b-cover:hover:has(.hover-actions) > span:not(.b-badge) { transform: translateY(-46px); }
.b-cover { width: 132px; aspect-ratio: 2 / 3; }
.b-cover.lg { width: 250px; }
/* On the Games row, covers grow from their left edge so the selected cover stays on the same left line as the hero title,
   Play button and the Recent / Favorites / A–Z bar. The 28px gap leaves room for the 20px it grows to the right. */
.b-cover.lg { transform-origin: left center; }
.b-cover > .art { position: absolute; inset: 0; border-radius: inherit; }
/* The selected game's hero becomes part of the wallpaper behind the whole Games page. Heroes are wide and short
   (Steam's are 3840 x 1240), so the hero spans the full width at the top at its own shape, never cropped or stretched,
   and a mirror image of it continues straight down underneath, so there's never an edge where the hero ends. The whole
   backdrop then fades softly into the wallpaper across the bottom half of the screen. Covers have no reflection. */
.b-backdrop { position: absolute !important; inset: 0; z-index: 0 !important; pointer-events: none; transition: opacity var(--br-motion-panel) var(--br-motion-ease-standard);
  -webkit-mask-image: linear-gradient(180deg, var(--br-shade-100) 0%, var(--br-shade-100) 40%, var(--br-shade-55) 62%, transparent 92%); mask-image: linear-gradient(180deg, var(--br-shade-100) 0%, var(--br-shade-100) 40%, var(--br-shade-55) 62%, transparent 92%); }
.b-backdrop > .hero { width: 100%; aspect-ratio: 3840 / 1240; background-size: cover; background-position: center; -webkit-box-reflect: below 0; }
.b-backdrop::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, var(--br-deep-70) 0%, var(--br-deep-30) 40%, transparent 70%), linear-gradient(180deg, transparent 45%, var(--br-deep-35) 100%); }

/* Now playing: compact */
.b-np { height: var(--br-size-control); display: inline-flex; align-items: center; gap: 10px; padding: 0 4px 0 5px; border-radius: var(--br-shape-radius); background: var(--br-glass-inset); border: 1px solid var(--br-glass-edge); box-shadow: var(--br-shadow-edge-light); }
.b-np .art { width: 30px; height: 30px; border-radius: 50%; flex: none; background: var(--br-now-playing-art-fallback) center / cover; box-shadow: inset 0 0 0 1px var(--br-tint-14); }
/* The album art is round: the real cover, cropped to a circle (stand-in here). */
.b-np .meta { display: flex; flex-direction: column; gap: 1px; max-width: 150px; margin-right: 4px; }
.b-np .meta b { font-size: 13px; line-height: 16px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.b-np .meta span { font-size: 12px; line-height: 15px; color: var(--br-text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.b-np .b-btn { width: 30px; height: 30px; padding: 0; justify-content: center; }
.b-np .b-btn + .b-btn { margin-left: -6px; }
.b-np .b-icon { width: 16px; height: 16px; }

/* Scrollbar: the ONE scrollbar for every scroll area in Bridge (and injected into web pages). Every scroller on a Bridge
   page gets it, .b-scroll or not, so the system's arrowed scrollbar never shows.
   6px glass pill at rest, 10px on hover or drag, no arrows, invisible track, 4px in from the edge. */
.b-scroll { overflow-x: hidden; overflow-y: auto; padding-inline: 4px; }
.b-scroll.h { overflow-x: auto; overflow-y: hidden; padding-inline: 0; padding-block: 8px; }
/* Shadows are never cut off. A scroll area clips whatever leaves its box, so every scroll area that holds tiles or
   lifted items gets a gutter as deep as the float shadow reaches, cancelled by an equal negative margin: the content
   still lines up exactly where it would, but a grown tile and its shadow (and a dragged item) have room to show.
   Gutters are 32px (24px inside a panel or dialog, 32px below) and tile shadows (--br-shadow-tile, --br-shadow-lift when grown)
   reach less than that, so no shadow is ever clipped by any container. */
.b-scroll.tiles { padding: 32px 32px 40px; margin: -32px -32px -40px; }
.b-scroll.tiles.h { padding: 32px 32px 44px; margin: -32px -32px -16px; }
.b-scroll.tiles-in { padding: 12px 24px 24px; margin: -8px -24px 0; }
/* Never set scrollbar-width or scrollbar-color for Chromium/WebView2: either one makes it ignore the rules below and draw native arrows. */
@supports not selector(::-webkit-scrollbar) { .b-scroll { scrollbar-width: thin; scrollbar-color: var(--br-tint-28) transparent; } }
.b-scroll::-webkit-scrollbar, .b-app *::-webkit-scrollbar { width: 14px; height: 14px; }
.b-scroll::-webkit-scrollbar-track, .b-app *::-webkit-scrollbar-track { background: transparent; margin: 12px; }
.b-scroll::-webkit-scrollbar-corner, .b-app *::-webkit-scrollbar-corner { background: transparent; }
.b-scroll::-webkit-scrollbar-button, .b-app *::-webkit-scrollbar-button { display: none; height: 0; width: 0; }
.b-scroll::-webkit-scrollbar-thumb, .b-app *::-webkit-scrollbar-thumb { background: var(--br-tint-28); border-radius: var(--br-shape-pill); border: 4px solid transparent; background-clip: padding-box; min-height: 40px; }
.b-scroll::-webkit-scrollbar-thumb:hover, .b-app *::-webkit-scrollbar-thumb:hover { border-width: 2px; background-color: var(--br-tint-40); }
.b-scroll::-webkit-scrollbar-thumb:active, .b-app *::-webkit-scrollbar-thumb:active { border-width: 2px; background-color: var(--br-tint-50); }
/* Shown only when it's of use (FIXES #77): the thumb appears while the pointer is over its scroller or it's scrolling
   (.is-scrolling, set for a second by any scroll: wheel, keys, controller), and is invisible the rest of the time. */
.b-app *:not(:hover):not(.is-scrolling)::-webkit-scrollbar-thumb { background-color: transparent; }
/* Quiet: for a grid that should sit centred in its frame (an app drawer). The scrollbar's room is kept on both sides,
   so the content is centred whether or not there is anything to scroll, and the thumb shows only while it is
   scrolling, not on hover. */
.b-scroll.quiet { scrollbar-gutter: stable both-edges; padding-inline: 0; }
.b-app .b-scroll.quiet:not(.is-scrolling)::-webkit-scrollbar-thumb, .b-scroll.quiet:not(.is-scrolling)::-webkit-scrollbar-thumb { background-color: transparent; }

/* Panels that sit beside a page: sidebars, details panels, flyout panels */
.b-panel { display: flex; flex-direction: column; gap: var(--br-space-2); padding: var(--br-space-3); min-height: 0; }
.b-side { width: 280px; flex: none; }

/* A web page, web app or Quick Look picture: content Bridge never restyles, in a 16px rounded frame */
.b-frame { border-radius: var(--br-shape-radius); overflow: hidden; background: var(--br-tint-100); color: var(--br-frame-text); box-shadow: var(--br-shadow-glass); min-width: 0; min-height: 0; }

/* Web view: the glass panel that marks where the page goes. With a page showing, the page fills the panel exactly
   (same box, same 16px corners) and covers it. With no page (new tab, loading, private new tab, error and certificate
   pages) the panel's glass shows, so you always see where the page lives. Nothing white ever flashes. */
.b-view { flex: 1; min-width: 0; min-height: 0; display: flex; gap: var(--br-space-2); padding: var(--br-space-2); position: relative; }
.b-view:has(> .b-frame) { padding: 0; gap: 0; border-color: transparent; background: transparent; box-shadow: var(--br-shadow-glass); border-radius: var(--br-shape-radius); }   /* rounded like the page, so its shadow's corners never show past the page's */
.b-view > .b-frame { flex: 1; box-shadow: none; }
.b-view.inside { flex-direction: column; align-items: center; justify-content: center; padding: var(--br-space-5); gap: var(--br-space-4); }
.b-load { position: absolute; top: 3px; left: var(--br-space-5); right: var(--br-space-5); height: 2px; border-radius: var(--br-shape-pill); overflow: hidden; z-index: 1; }
.b-load > i { position: absolute; inset: 0 auto 0 0; border-radius: inherit; background: var(--br-accent-primary); }

/* Settings row: label left, control right, optional one-line description */
.b-srow { min-height: calc(var(--br-size-control-lg) + 4px); padding: var(--br-space-2) var(--br-space-4); display: flex; align-items: center; gap: var(--br-space-4); border-radius: var(--br-shape-radius); }
/* Rows never light up on hover: only their control is clickable (rules: only what you can act on as a whole highlights). */
.b-srow .txt { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.b-srow .txt span { font-size: 12px; line-height: 16px; color: var(--br-text-secondary); }

/* Dialogs: one glass over a scrim, centred, title + body + buttons right */
.b-scrim { position: absolute; inset: 0; background: var(--br-surface-scrim); }
.b-dialog { width: 440px; padding: var(--br-space-5); display: flex; flex-direction: column; gap: var(--br-space-4); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.b-dialog .actions { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--br-space-2); }
.b-dialog .actions > .b-btn { min-width: 0; white-space: nowrap; }

/* Badges and keys */
.b-badge { height: 20px; padding: 0 8px; display: inline-flex; align-items: center; border-radius: var(--br-shape-radius); background: var(--br-glass-lift-strong); color: var(--br-text-primary); font: 600 11px/16px var(--br-font-ui); }
.b-badge.accent { background: var(--br-accent-primary); color: var(--br-text-on-accent); }
/* Update ready: lit like a selected item (the neon edge), so it's easy to see on a cover. */
.b-badge.update { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); color: var(--br-text-primary); }
.b-kbd { min-width: 22px; height: 22px; padding: 0 6px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--br-shape-radius); background: var(--br-glass-inset); border: 1px solid var(--br-glass-edge); font: 500 11px/16px var(--br-font-mono); color: var(--br-text-secondary); }

/* Spinner: the one busy indicator */
.b-spin { width: 16px; height: 16px; border-radius: var(--br-shape-pill); border: 2px solid var(--br-glass-lift-strong); border-top-color: var(--br-text-primary); flex: none; }

/* One glass everywhere, even over a web page, a web app or a game: it always shows what's behind it, blurred. Over
   bright content (the app reads the brightness behind each panel; see Readability) the same glass turns light, like
   Flowdesk: a see-through white with a white rim and a fine dark hairline, soft blue-grey shadows, black text, white
   fields, and a white selected pill with the violet glow inside it. A light wallpaper gets this too. Mockups mark
   that state with .on-bright. */
.on-bright, .on-bright .b-glass {
  --br-glass-tint: var(--br-tint-30);
  --br-text-primary: var(--br-bright-text-primary); --br-text-secondary: var(--br-bright-text-secondary); --br-text-tertiary: var(--br-bright-text-tertiary);
  --br-glass-lift: var(--br-tint-50); --br-glass-lift-strong: var(--br-tint-70); --br-glass-inset: var(--br-tint-60); --br-glass-edge: var(--br-bright-edge-12);
  --br-shadow-edge-light: inset 0 1px 0 var(--br-tint-100), 0 0 0 0.5px var(--br-bright-edge-16);
  --br-shadow-glass: 0 10px 22px var(--br-bright-shadow-13), 0 3px 8px var(--br-bright-shadow-7), 0 1px 2px var(--br-bright-shadow-6);
  --br-shadow-float: 0 12px 24px var(--br-bright-shadow-16), 0 4px 10px var(--br-bright-shadow-8), 0 1px 3px var(--br-bright-shadow-6);
  --br-shadow-lift: 0 4px 12px var(--br-bright-shadow-12), 0 1px 3px var(--br-bright-shadow-6);
  /* Status colours deep enough to read on light glass (the light ones are made for dark glass). */
  --br-state-danger: var(--br-bright-state-danger); --br-state-success: var(--br-bright-state-success); --br-state-warning: var(--br-bright-state-warning);
  /* Selected: a white pill with the violet glow inside its edge. */
  --br-selected-fill: var(--br-tint-88);
  --br-selected-edge: inset 0 0 0 1px rgba(var(--br-accent-primary-rgb), 0.85), inset 0 0 0 2px rgba(var(--br-accent-primary-rgb), 0.25), inset 0 0 5px rgba(var(--br-accent-primary-rgb), 0.30),
    inset 0 0 24px rgba(var(--br-accent-primary-rgb), 0.48), 0 2px 6px var(--br-shade-14);   /* light: the glow is inside only */
  --br-highlight-edge: inset 0 0 0 1px rgba(var(--br-accent-primary-rgb), 0.85), 0 0 0 1px rgba(var(--br-accent-primary-rgb), 0.25), 0 0 6px rgba(var(--br-accent-primary-rgb), 0.30);   /* light: the edge, no glow inside */
  --br-highlight-line: rgba(var(--br-accent-primary-rgb), 0.85);
  --br-highlight-glow: 0 0 0 1px rgba(var(--br-accent-primary-rgb), 0.25), 0 0 6px rgba(var(--br-accent-primary-rgb), 0.30);
  color: var(--br-text-primary); /* text that sets no colour of its own inherits the computed light ink otherwise */
}
/* Selected text: the accent behind it with white text, in both modes (black on blue read badly). */
::selection { background: color-mix(in srgb, var(--br-accent-primary) 85%, var(--br-shade-100)); color: var(--br-tint-100); }
/* The wallpaper layer also covers the 1px border, so a bright page never shows through the edge; the edge is drawn on it instead. */
.b-frame { position: relative; }

/* The same scrollbar injected into web pages and web apps: identical shape and behaviour, a neutral grey thumb
   that reads on both light and dark sites. */
.b-scroll.page::-webkit-scrollbar-thumb { background-color: var(--br-page-scrollbar); }
.b-scroll.page::-webkit-scrollbar-thumb:hover, .b-scroll.page::-webkit-scrollbar-thumb:active { background-color: var(--br-page-scrollbar-hover); }

/* Glass inside glass: buttons and fields inside any glass surface drop their own blur and use the inset fill. */
.b-glass .b-btn:not(.primary):not(.quiet) { background: var(--br-glass-inset); -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
/* A field inside glass is an outlined pill (F1's search): no fill of its own, a clear edge. On light glass it's a white well. */
.b-glass .b-field { background: transparent; border-color: var(--br-tint-26); border-radius: var(--br-shape-pill); -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
/* A glass field inside a glass panel (the new-tab search) looks exactly like one on the wallpaper (Home's): the panel's
   glass already shows behind it once, so it adds no tint or blur of its own, only its edge, edge light and shadow. */
.b-glass .b-field.on-wall { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: var(--br-shadow-edge-light), var(--br-shadow-glass); }
.b-glass .b-btn:not(.primary):not(.quiet):hover, .b-glass .b-btn.is-focus:not(.primary):not(.quiet), .b-glass .b-btn.is-pad-focus:not(.primary):not(.quiet) { box-shadow: var(--br-highlight-edge); }

/* Files: everything selected (places, tiles, rows, search results) uses the same tint and accent edge as switches and tabs. */
.b-files .is-selected { background: var(--br-selected-fill) !important; box-shadow: var(--br-selected-edge); }
.b-files .b-tile.is-selected { box-shadow: var(--br-selected-edge), var(--br-shadow-lift); }

/* Editors (PDF, picture, video): a tool rail on the left, the inspector for the current tool on the right. */
.b-rail { display: flex; flex-direction: column; gap: 4px; padding: 6px; flex: none; }
.b-rail > .b-btn { width: 40px; min-width: 0; }
.b-rail > .b-btn.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); color: var(--br-text-primary); }
.b-swatch { width: 24px; height: 24px; border-radius: 50%; flex: none; box-shadow: inset 0 0 0 1px var(--br-tint-18); }
.b-swatch.is-selected { box-shadow: 0 0 0 2px var(--br-glass-tint), 0 0 0 4px var(--br-accent-primary); }
.b-srow .b-btn:not(.b-icon-btn), .b-item .end .b-btn:not(.b-icon-btn), .b-toast .b-btn { min-width: 112px; }
.b-toast > .dot + span, .b-toast.sel > span:first-child { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.b-toast.sel > .b-btn:not(.b-icon-btn) { min-width: 0; }

/* Start-screen clock: thin numerals made of frosted Bridge glass, with no outline. A blurred, brightened layer (.fill)
   is clipped to the digits by an SVG clipPath, so the wallpaper glows through them; .shade is a soft shadow under them.
   The face is set with --clock-font / --clock-weight (thin and elegant). */
.b-glass-clock { position: relative; width: 680px; height: 230px; --clock-font: "Inter Tight", var(--br-font-ui); --clock-weight: 500; }
.b-glass-clock text { font-family: var(--clock-font); font-weight: var(--clock-weight); font-size: 220px; letter-spacing: -4px; font-variant-numeric: tabular-nums; }
.b-glass-clock > svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.b-glass-clock .fill { position: absolute; inset: 0; clip-path: url(#b-clock-clip); background: var(--br-tint-34);
  -webkit-backdrop-filter: blur(var(--br-glass-blur)) saturate(1.8) brightness(1.5); backdrop-filter: blur(var(--br-glass-blur)) saturate(1.8) brightness(1.5); }
.b-glass-clock .shade text { fill: var(--br-shade-28); filter: blur(var(--br-clock-shade-blur)); transform: translateY(6px); }
.b-glass-clock .edge { display: none; }

/* The game overlay sits in a frame, not glass: blur can't reach under an exclusive full-screen game. */
.b-hud { background: var(--br-hud-surface); border: 1px solid var(--br-tint-14); border-radius: var(--br-shape-radius); box-shadow: 0 4px 12px var(--br-shade-35); }

/* Nothing is ever clipped by its scroller: every list scroller keeps a gutter as wide as a grown row or tile needs
   (a 1.02x row on a 1000px list sticks out 10px), and pulls it back with a matching negative margin so content
   still lines up with headers. Inset wells and web pages size their own padding. */
.b-scroll:not(.page):not(.b-inset):not(.b-panel):not(.b-glass):not(.b-menu):not(.h):not(.tiles):not(.tiles-in) { padding: 8px 14px; margin: -8px -14px; }

/* Selected text is always full-strength ink, including the secondary text. */
.is-selected, .is-selected .b-muted, .is-selected .caption, .is-selected .b-label { color: var(--br-text-primary) !important; }
.is-selected .b-muted, .is-selected .caption { opacity: 0.9; }
.is-selected b, .b-item.is-selected > span { font-weight: 600; }

/* Settings sections open and close (a disclosure, like macOS System Settings groups) so every tab fits at a glance.
   The header is a 48px row; the chevron turns and the rows slide open (dur-move, standard curve). */
.b-sgroup { border-radius: var(--br-shape-radius); }
.b-sgroup > summary { list-style: none; height: 48px; padding: 0 var(--br-space-4); display: flex; align-items: center; gap: var(--br-space-3);
  border-radius: var(--br-shape-radius); cursor: pointer; background: var(--br-glass-lift); transition: background var(--br-motion-move) var(--br-motion-ease-standard); }
.b-sgroup > summary::-webkit-details-marker { display: none; }
.b-sgroup > summary:hover { box-shadow: var(--br-highlight-edge); }
.b-sgroup > summary .t { flex: 1; font-weight: 600; }
.b-sgroup > summary .b-icon { transition: transform var(--br-motion-move) var(--br-motion-ease-standard); color: var(--br-text-secondary); }
.b-sgroup[open] > summary .b-icon { transform: rotate(180deg); }
.b-sgroup[open] > summary .b-num { display: none; }
.b-sgroup > .rows { display: flex; flex-direction: column; gap: 2px; padding: 6px 0 12px; }

/* Edge pill: when a side panel is on auto-hide (the browser's sidebar on the left, Files' Details on the right), a small
   glass pill sits in the screen-edge gutter, centred top to bottom, so you know a flyout is there. Hover or click it
   (or move the pointer / D-pad to that edge) and the panel slides in; the pill fades out while the panel is open. */
.b-edge-pill { position: absolute; top: 50%; width: 5px; height: 64px; margin-top: -32px; border-radius: var(--br-shape-pill); z-index: 6;
  background: var(--br-tint-55); box-shadow: 0 0 0 1px var(--br-tint-12), 0 2px 8px var(--br-shade-35);
  transition: width var(--br-motion-move) var(--br-motion-ease-standard), height var(--br-motion-move) var(--br-motion-ease-standard), opacity var(--br-motion-move) var(--br-motion-ease-standard); }
.b-edge-pill.left { left: 5px; } .b-edge-pill.right { right: 5px; }
/* A side panel that hides (Files' and Games' Details, like the browser's sidebar): the invisible strip on the screen's edge opens it too. */
.b-edge-gutter { position: absolute; top: 0; bottom: 0; width: 22px; z-index: 5; }
.b-edge-gutter.right { right: 0; }
.b-autopanel { position: absolute; right: 0; top: 0; bottom: 0; z-index: 5; display: flex; }
.b-autopanel > .b-panel { height: auto; }
.b-edge-pill:hover { width: 6px; height: 80px; margin-top: -40px; background: var(--br-tint-80); }

/* A toast can carry progress (downloads, copies): a 3px accent line along its bottom edge, inside the rounded corners. */
.b-toast { position: relative; overflow: hidden; }
.b-toast > .progress { position: absolute; left: 0; bottom: 0; height: 3px; background: var(--br-accent-primary); border-radius: 0 var(--br-shape-radius-2) var(--br-shape-radius-2) 0; transition: width var(--br-motion-move) linear; }

/* Every notification offers its action (or Show) and Dismiss. Toast buttons are a fixed pair (96px each);
   notification cards keep them small: a right-aligned row of two 28px buttons under the text. */
.b-toast:not(.sel) .b-btn:not(.b-icon-btn) { min-width: 96px; }
.note-acts { display: flex; justify-content: flex-end; gap: 6px; margin-top: 6px; }
.note-acts .b-btn { height: 28px; min-width: 76px; padding: 0 10px; font-size: 12px; }

/* The browser's tab list never grows the current tab: it is marked by its tint alone, so the list stays still. */
.b-side .b-item.is-selected { transform: none; }

/* Bridge's own pages. The app draws the wallpaper and the glass blur behind every page it shows, so the page itself is
   see-through (the body background above is for previews). Put .b-app on the <html> of every Bridge page. */
html.b-app, html.b-app body { height: 100%; background: transparent; overflow: hidden; }

/* The white / black switch fades (Readability): the content colours are registered so they can transition, and every
   panel that can switch fades them together over --br-motion-ink. The glass itself never changes. */
@property --br-text-primary { syntax: "<color>"; inherits: true; initial-value: #f4f6fb; }
@property --br-text-secondary { syntax: "<color>"; inherits: true; initial-value: #aeb6c7; }
@property --br-text-tertiary { syntax: "<color>"; inherits: true; initial-value: #7c859a; }
@property --br-glass-lift { syntax: "<color>"; inherits: true; initial-value: transparent; }
@property --br-glass-lift-strong { syntax: "<color>"; inherits: true; initial-value: transparent; }
@property --br-glass-inset { syntax: "<color>"; inherits: true; initial-value: transparent; }
@property --br-glass-tint { syntax: "<color>"; inherits: true; initial-value: transparent; }
@property --br-glass-edge { syntax: "<color>"; inherits: true; initial-value: transparent; }
.b-glass, .b-field.on-wall {
  transition: --br-text-primary var(--br-motion-ink) var(--br-motion-ease-standard), --br-text-secondary var(--br-motion-ink) var(--br-motion-ease-standard), --br-text-tertiary var(--br-motion-ink) var(--br-motion-ease-standard),
    --br-glass-lift var(--br-motion-ink) var(--br-motion-ease-standard), --br-glass-lift-strong var(--br-motion-ink) var(--br-motion-ease-standard),
    --br-glass-inset var(--br-motion-ink) var(--br-motion-ease-standard), --br-glass-edge var(--br-motion-ink) var(--br-motion-ease-standard), --br-glass-tint var(--br-motion-ink) var(--br-motion-ease-standard);
}

/* Hover equals focus, and nothing ever gets a focus ring: keyboard and controller focus look exactly like the mouse over it. */
:focus-visible { outline: none; }
.b-btn:focus-visible { box-shadow: var(--br-highlight-edge); }
.b-btn.quiet:focus-visible, .b-glass .b-btn:not(.primary):not(.quiet):focus-visible { box-shadow: var(--br-highlight-edge); }
.b-tab:focus-visible, .b-status:focus-visible, .b-logo:focus-visible, .b-item:focus-visible, .b-srow:focus-visible { box-shadow: var(--br-highlight-edge); }
.b-tab:focus-visible { color: var(--br-text-primary); }
.b-sgroup > summary:focus-visible { box-shadow: var(--br-highlight-edge); }
.b-tile:focus-visible { transform: scale(var(--br-motion-tile-scale)); box-shadow: var(--br-highlight-edge), var(--br-shadow-lift); }
.b-chip:focus-visible, .b-toggle:focus-visible, .b-seg > span:focus-visible { box-shadow: var(--br-highlight-edge); }
.b-seg > span.is-pad-focus { box-shadow: var(--br-highlight-edge); }

/* The one highlight that slides (switches and top bar tabs). In the app the selected option draws no fill of its own; a
   single .b-slide carries it. At rest it sits in the selected option's own grid cell (column --c), so it lines up with
   the option to the pixel; when the selection changes the app glides it from the old cell to the new one with a
   transform (--br-motion-move, standard curve). Options are equal width, so it never changes size. Each option sits in its
   own column (the app numbers them) and above the highlight. */
.b-slide { grid-row: 1; grid-column: var(--c); align-self: stretch; border-radius: var(--br-shape-radius); background: var(--br-selected-fill); box-shadow: var(--br-selected-edge);
  pointer-events: none; transition: opacity var(--br-motion-move) var(--br-motion-ease-standard); }
.b-tabs > .b-slide { transform: scale(var(--br-motion-select-scale)); }
.b-slide.none { opacity: 0; }
.b-seg:has(> .b-slide) > span, .b-tabs:has(> .b-slide) > .b-tab { grid-row: 1; position: relative; }
.b-seg:has(> .b-slide) > span.is-selected, .b-tabs:has(> .b-slide) > .b-tab.is-selected { background: none; box-shadow: none; }

/* A selected (or focused) settings row grows and brightens like every other row. */
.b-srow { transition: transform var(--br-motion-move) var(--br-motion-ease-standard), background-color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-srow.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); transform: scale(1.02); }

/* The spinner turns once every --br-motion-spin, steadily. */
@keyframes b-spin { to { transform: rotate(360deg); } }
.b-spin { animation: b-spin var(--br-motion-spin) linear infinite; }

/* A button whose flyout or menu is open (top-bar status icons, Power) keeps the stronger lift and grows like a
   selected item; the More tab whose menu is open shows the hover lift. */
.b-btn.is-open, .b-btn.quiet.is-open { box-shadow: inset 0 0 0 999px var(--br-glass-lift-strong); transform: scale(var(--br-motion-select-scale)); }
.b-tab.is-open { color: var(--br-text-primary); background: var(--br-glass-lift); }
.b-tab .b-icon { width: 14px; height: 14px; }

/* An icon-only switch (Row / Grid on the Games top bar): square 40px options. */
.b-seg.icons > span { width: var(--br-size-control); padding: 0; }

/* A tab being dragged lifts onto the float shadow and follows the pointer; the rest glide aside to open its gap. */
.b-tab.is-dragging, .b-btn.is-dragging { z-index: 2; box-shadow: var(--br-shadow-float); background: var(--br-glass-lift-strong); color: var(--br-text-primary); transition: none; }

/* Something waiting (the bell when notifications are unread): a small accent dot at the icon's top right. */
.b-icon-btn.has-dot { position: relative; }
.b-icon-btn.has-dot::after { content: ""; position: absolute; top: 6px; right: 6px; width: 7px; height: 7px; border-radius: var(--br-shape-pill); background: var(--br-accent-primary);
  box-shadow: 0 0 0 2px var(--br-glass-tint); }

/* A switch keeps its size wherever it sits (inside a row's end slot it would otherwise lay out as text). */
.b-toggle { display: inline-block; vertical-align: middle; }

/* Calculator (the Calculator flyout, Standard): an inset display with the calculation above the result, a row of
   memory keys, and a four-column keypad of 52px keys (digits on glass, the rest quiet, = in accent). */
.b-calc-display { padding: 12px 14px 10px; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.b-calc-display .expr { min-height: 20px; font-size: 14px; line-height: 20px; font-variant-numeric: tabular-nums; color: var(--br-text-secondary); white-space: nowrap; }
.b-calc-display output { flex: 1; text-align: right; font-size: 44px; line-height: 52px; font-weight: 600; letter-spacing: -0.5px; font-variant-numeric: tabular-nums;
  white-space: nowrap; transform-origin: right center; }
.b-keypad { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.b-keypad > .b-btn { min-width: 0; height: var(--br-size-control-lg); padding: 0; font-size: 18px; }
.b-keypad-mem { display: flex; gap: 2px; }
.b-keypad-mem > .b-btn { min-width: 0; flex: 1; padding: 0; }

/* In the app the page is drawn by Bridge under its own interface, so the frame that marks it is see-through. */
.b-frame.hosted { background: transparent; }

/* Fields on bright glass: a near-solid light fill with a hairline edge (a thicker layer on top, like iOS search fields),
   not a darker tint of the panel. */
/* Light content on light glass: the panel's rim is white like the glass's own edge light; fields and keys are white
   wells with a hairline. */
.b-glass.on-bright, .on-bright .b-glass { border-color: var(--br-tint-85); }
.on-bright .b-field:not(.on-wall), .b-glass.on-bright .b-field:not(.on-wall) { background: var(--br-tint-88); border-color: var(--br-bright-edge-10); box-shadow: 0 2px 8px var(--br-bright-shadow-8); }
.on-bright .b-field input::placeholder { color: var(--br-text-primary); opacity: 0.9; }
.on-bright .b-kbd, .b-glass.on-bright .b-kbd { background: var(--br-tint-70); border-color: var(--br-bright-kbd-edge); }

/* The pointer works the way you'd expect: the arrow by default, including over words (no text
   cursor over labels and titles); the hand on anything you can click; the text cursor only where you type; resize
   arrows on the resize handles (sidebar width, split view). A row counts as clickable when it has an action (data-click). */
html { cursor: default; }
a[href], button, summary, select, label[for], [role="button"], [role="tab"], [role="link"], [role="switch"], [role="checkbox"],
[role="radio"], [role="menuitemradio"], [role="menuitemcheckbox"], [role="slider"], [role="option"], .b-item[data-click],
.b-btn, .b-icon-btn, .b-tab, .b-logo, .b-chip, .b-seg > span, .b-toggle, .b-track, .b-tile, .b-srow, .b-status,
input[type="checkbox"], input[type="radio"], input[type="range"], input[type="button"], input[type="submit"], input[type="color"], input[type="file"] { cursor: pointer; }
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="button"]):not([type="submit"]):not([type="color"]):not([type="file"]),
textarea, [contenteditable]:not([contenteditable="false"]) { cursor: text; }
[disabled], [aria-disabled="true"], [disabled] *, [aria-disabled="true"] * { cursor: default; }
[role="separator"][aria-label^="Resize"] { cursor: ew-resize; }

/* Text isn't selectable, except where selecting it makes sense: text fields, and text marked
   [data-selectable] (a dialog's message, a notification, a toast's detail, an error's explanation, the calculator's
   result). Labels, titles and controls never highlight on a drag or a double-click. */
html { -webkit-user-select: none; user-select: none; }
input, textarea, [contenteditable]:not([contenteditable="false"]), [data-selectable], [data-selectable] * { -webkit-user-select: text; user-select: text; }

/* Light, everywhere it applies: things inside a light area that aren't glass panels of their own
   (Home's search, a button or chip on its own) take the light look too; a switch that's off is a white knob on a grey
   track; a dialog (always over the dimmed backdrop) is a thicker white so its message reads; and in Light mode the
   backdrop behind a dialog is a soft dim, not a dark one. */
.on-bright .b-toggle:not(.on) { background: var(--br-bright-edge-14); box-shadow: none; }
.on-bright .b-toggle:not(.on)::after { background: var(--br-tint-100); box-shadow: 0 1px 3px var(--br-shade-25), 0 0 0 0.5px var(--br-shade-8); }
.b-dialog.on-bright, .on-bright .b-dialog { --br-glass-tint: var(--br-tint-82); }
/* The outline marking split view's active side sits on the wallpaper: white, or near-black in Light mode. */

/* Files (boards FilesGrid, FilesList, FilesDetailsAutoHide). Grid tiles: a 4:3 picture (a thumbnail, or the item's
   icon, folders in yellow) and the name under it; List rows: Name, Date modified, Type, Size. Selected items use the
   one selected look (.b-files .is-selected); tiles grow a little. */
.b-ftile { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 8px 8px 10px; border-radius: var(--br-shape-radius);
  transition: transform var(--br-motion-move) var(--br-motion-ease-standard), background-color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-ftile:hover { box-shadow: var(--br-highlight-edge); }
.b-ftile.is-selected { transform: scale(1.03); }
.b-ftile .pic { position: relative; width: 100%; aspect-ratio: 4 / 3; border-radius: var(--br-shape-radius-12); display: grid; place-items: center; background: center / cover no-repeat; }
.b-ftile .pic.has-art { box-shadow: 0 4px 12px var(--br-shade-22); }
.ficon { display: grid; place-items: center; }
.ficon .b-icon { width: 44px; height: 44px; stroke-width: 1.4; color: var(--br-text-secondary); }
.ficon.folder .b-icon { color: var(--br-files-folder); }
.on-bright .ficon.folder .b-icon { color: var(--br-bright-files-folder); }
.b-ftile .play { position: absolute; inset: 0; display: grid; place-items: center; }
.b-ftile .play .b-icon { width: 30px; height: 30px; color: var(--br-tint-100); fill: var(--br-tint-100); filter: drop-shadow(0 1px 3px var(--br-shade-50)); }
.b-ftile .nm { max-width: 100%; padding-inline: 2px; font: 600 13px/16px var(--br-font-ui); text-align: center; overflow: hidden; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.b-frow { display: grid; grid-template-columns: minmax(0, 2.2fr) minmax(150px, 1.2fr) minmax(110px, 1fr) 90px; align-items: center; gap: 12px;
  height: 40px; padding: 0 12px; border-radius: var(--br-shape-radius-12); transition: background-color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-frow:not(.head):hover { box-shadow: var(--br-highlight-edge); }
.b-frow.head { height: 32px; }
.b-fhead { all: unset; display: flex; align-items: center; gap: 4px; font: 600 11px/16px var(--br-font-display); letter-spacing: 0.8px; text-transform: uppercase; color: var(--br-text-secondary); cursor: pointer; }
.b-fhead .b-icon { width: 12px; height: 12px; }
.b-frow .name { display: flex; align-items: center; gap: 10px; min-width: 0; }
.b-frow .name > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.b-frow .name .b-icon { color: var(--br-text-secondary); }
.b-frow .b-num { font-size: 13px; }
.b-fpreview { aspect-ratio: 4 / 3; border-radius: var(--br-shape-radius); background: var(--br-glass-inset) center / cover no-repeat; display: grid; place-items: center; box-shadow: var(--br-shadow-lift); }
.b-fkv { display: grid; grid-template-columns: auto 1fr; gap: 6px 16px; font-size: 13px; line-height: 18px; }
.b-fkv .b-num { overflow-wrap: anywhere; }

/* Files: the box dragged to select, a name being typed in place, and Details' stacked preview for several items. */
.b-fbox { position: absolute; z-index: 3; pointer-events: none; border-radius: var(--br-shape-radius-6); border: 1px solid color-mix(in srgb, var(--br-accent-primary) 80%, transparent);
  background: color-mix(in srgb, var(--br-accent-primary) 16%, transparent); }
.b-frename { width: 100%; min-width: 0; box-sizing: border-box; padding: 3px 6px; border-radius: var(--br-shape-radius-8); outline: none; font: 600 13px/18px var(--br-font-ui);
  color: var(--br-text-primary); background: var(--br-glass-inset); border: 1px solid color-mix(in srgb, var(--br-accent-primary) 70%, transparent); }
.on-bright .b-frename { background: var(--br-tint-100); }
.b-fstack { position: relative; aspect-ratio: 4 / 3; }
.b-fstack > span { position: absolute; left: calc(var(--k) * 17%); top: calc(var(--k) * 12%); width: 64%; aspect-ratio: 4 / 3; border-radius: var(--br-shape-radius-14);
  background: var(--br-glass-inset) center / cover no-repeat; box-shadow: var(--br-shadow-lift); display: grid; place-items: center; }

/* Files: dragging. The folder or place a drag would land in shows an accent outline; dropping on the file panel itself
   (the folder Files shows) outlines the panel; a chip with the count follows the pointer. */
.b-files .is-drop { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--br-accent-primary) 85%, transparent); background: color-mix(in srgb, var(--br-accent-primary) 14%, transparent); }
.is-drop-area { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--br-accent-primary) 70%, transparent); }
.b-fghost { position: fixed; z-index: 30; pointer-events: none; display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px 0 12px;
  border-radius: var(--br-shape-radius-12); font: 650 14px/18px var(--br-font-ui); color: var(--br-text-primary); background: var(--br-drag-badge);
  box-shadow: inset 0 0 0 1px var(--br-tint-18), inset 0 1px 0 var(--br-tint-30), 0 10px 24px var(--br-shade-35); }
.b-fghost .b-icon { width: 16px; height: 16px; }
.b-fghost b { min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--br-shape-radius-10); display: grid; place-items: center; font: 700 12px/1 var(--br-font-ui);
  color: var(--br-text-on-accent); background: var(--br-accent-primary); }
/* Search results: the name over its folder's path, and the size. */
.b-frow.res { grid-template-columns: minmax(0, 1fr) 90px; height: 54px; }
.b-frow.res .two { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.b-frow.res .two > * { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.b-frow.res small { font-size: 12px; line-height: 16px; }

/* Files › Recycle Bin: Name, Original location, Date deleted, Size, and Restore on the selected or pointed-at row. */
.b-frow.bin { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1.3fr) 150px 80px 96px; }
.b-frow.bin .act { display: flex; justify-content: flex-end; visibility: hidden; }
.b-frow.bin:hover .act, .b-frow.bin.is-selected .act { visibility: visible; }
.b-frow.bin .act .b-btn { min-width: 0; height: 30px; padding: 0 14px; }

/* Files' viewer (boards FilesViewImage, FilesViewVideo, FilesViewPdf): one glass panel over Files (or the whole window
   in full screen); the header; the stage with the file, previous / next arrows, and a floating glass bar. */
.b-viewer { position: absolute; inset: 0; z-index: 8; display: flex; flex-direction: column; gap: 10px; padding: 12px 14px 14px; box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
/* Full screen: the whole window, black behind the picture, nothing of Bridge showing; same header and tools. */
.b-viewer.full { position: fixed; inset: 0; z-index: 15; border-radius: 0; border-color: transparent; background: var(--br-shade-100); box-shadow: none; }
.b-viewer.full .stage { border-radius: var(--br-shape-radius-10); background: var(--br-shade-100); }
.b-viewer > header { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 4px; }
.b-viewer > header .nm { font: 650 16px/20px var(--br-font-ui); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.b-viewer .stage { position: relative; flex: 1; min-height: 0; display: flex; border-radius: var(--br-shape-radius-14); overflow: hidden; background: var(--br-shade-22); }
.b-viewer .pic { position: relative; flex: 1; min-width: 0; overflow: hidden; }
.b-viewer .pic img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; transition: transform var(--br-motion-move) var(--br-motion-ease-standard); user-select: none; }
.b-viewer .vid { flex: 1; min-width: 0; width: 100%; height: 100%; object-fit: contain; background: var(--br-shade-100); }
.b-varrow { all: unset; position: absolute; top: 50%; z-index: 3; width: 40px; height: 40px; margin-top: -20px; border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  color: var(--br-tint-100); background: var(--br-smoke-45); backdrop-filter: blur(var(--br-glass-blur)); box-shadow: inset 0 0 0 1px var(--br-tint-22); }
.b-varrow.left { left: 16px; } .b-varrow.right { right: 16px; }
.b-varrow:hover { background: var(--br-smoke-60); }
.b-vbar { position: absolute; left: 50%; bottom: 16px; z-index: 3; transform: translateX(-50%); display: flex; align-items: center; gap: 4px; padding: 4px 8px; border-radius: var(--br-shape-radius-14); }
.b-vbar.wide { left: 24px; right: 24px; transform: none; gap: 12px; padding: 6px 14px; }
.b-vbar .sep { width: 1px; height: 20px; margin: 0 4px; background: var(--br-glass-edge); }
.b-vzoom { all: unset; min-width: 44px; text-align: center; font-weight: 650; cursor: pointer; }
.b-vthumbs { width: 104px; flex: none; overflow-y: auto; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 12px 8px; background: var(--br-shade-12); }
.b-vthumbs .th { all: unset; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 6px; border-radius: var(--br-shape-radius-12); }
.b-vthumbs .th > span { width: 64px; border-radius: var(--br-shape-radius-3); background: var(--br-tint-100) center / 100% 100% no-repeat; box-shadow: 0 2px 6px var(--br-shade-30); }
.b-vthumbs .th.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }
.b-viewer .pdf { flex: 1; min-width: 0; overflow: auto; display: flex; justify-content: center; align-items: flex-start; padding: 32px 24px 90px; }
.b-viewer .pdf .sheet { flex: none; background: var(--br-tint-100) center / 100% 100% no-repeat; box-shadow: 0 8px 24px var(--br-shade-35); }
/* While the viewer is open, the panels under it go (glass over glass would show them through). */
.b-files.viewing > :not(.b-viewer) { display: none !important; }

/* The picture editor (the viewer's Edit mode): the tool rail, the picture with crop box and marks, the 280px inspector. */
.b-viewer > header .b-seg { flex: none; }
.b-vsep { width: 1px; height: 20px; margin: 0 4px; background: var(--br-glass-edge); flex: none; }
.b-vedit { flex: 1; min-height: 0; display: flex; gap: 10px; }
.b-vrail { flex: none; width: 52px; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 6px 0; border-radius: var(--br-shape-radius-14); background: var(--br-glass-lift); }
.b-vrail .is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }
.b-vedit .ed-area { align-items: center; justify-content: center; }
.ed-frame { position: relative; flex: none; touch-action: none; box-shadow: 0 8px 24px var(--br-shade-35); }
.ed-frame canvas { display: block; width: 100%; height: 100%; }
.ed-frame.tool-draw, .ed-frame.tool-shapes { cursor: crosshair; }
.ed-frame.tool-text { cursor: text; }
.ed-crop { position: absolute; cursor: move; box-shadow: 0 0 0 9999px var(--br-shade-55), inset 0 0 0 1px var(--br-tint-90);
  background: linear-gradient(var(--br-tint-35), var(--br-tint-35)) 33.33% 0 / 1px 100% no-repeat,
    linear-gradient(var(--br-tint-35), var(--br-tint-35)) 66.66% 0 / 1px 100% no-repeat,
    linear-gradient(var(--br-tint-35), var(--br-tint-35)) 0 33.33% / 100% 1px no-repeat,
    linear-gradient(var(--br-tint-35), var(--br-tint-35)) 0 66.66% / 100% 1px no-repeat; }
.ed-crop .h { position: absolute; width: 16px; height: 16px; border-radius: var(--br-shape-radius-4); background: var(--br-tint-100); box-shadow: 0 1px 4px var(--br-shade-40); }
.ed-crop .nw { left: -8px; top: -8px; cursor: nwse-resize; } .ed-crop .se { right: -8px; bottom: -8px; cursor: nwse-resize; }
.ed-crop .ne { right: -8px; top: -8px; cursor: nesw-resize; } .ed-crop .sw { left: -8px; bottom: -8px; cursor: nesw-resize; }
.ed-picked { position: absolute; pointer-events: none; margin: -4px; padding: 4px; outline: 1.5px dashed var(--br-accent-primary); border-radius: var(--br-shape-radius-4); }
.b-vinspector { flex: none; width: 280px; overflow-y: auto; display: flex; flex-direction: column; gap: 12px; padding: 14px; border-radius: var(--br-shape-radius-14); background: var(--br-glass-lift); }
.b-vinspector .ed-title { font: 650 16px/20px var(--br-font-ui); }
.ed-group { display: flex; flex-direction: column; gap: 10px; }
.ed-group > summary { cursor: pointer; list-style: none; padding: 4px 0; }
.ed-group > summary::-webkit-details-marker { display: none; }
.ed-group[open] > summary { margin-bottom: 6px; }
.ed-slider { display: grid; grid-template-columns: 1fr auto; gap: 4px 8px; align-items: center; }
.ed-slider > .b-slider, .ed-slider > :last-child { grid-column: 1 / -1; }
.ed-buttons { display: flex; gap: 8px; } .ed-buttons > * { flex: 1; }
.ed-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ed-swatches { display: flex; flex-wrap: wrap; gap: 10px; }
.ed-swatches .b-swatch { all: unset; width: 24px; height: 24px; border-radius: 50%; cursor: pointer; box-shadow: inset 0 0 0 1px var(--br-tint-30), 0 1px 3px var(--br-shade-30); }
.ed-swatches .b-swatch.is-selected { box-shadow: 0 0 0 2px var(--br-glass-tint), 0 0 0 4px var(--br-accent-primary); }
.ed-filters { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.ed-filters .f { all: unset; cursor: pointer; display: flex; flex-direction: column; gap: 4px; padding: 6px; border-radius: var(--br-shape-radius-12); text-align: center; }
.ed-filters .f > span { aspect-ratio: 4 / 3; border-radius: var(--br-shape-radius-8); background: var(--br-shade-20) center / cover no-repeat; }
.ed-filters .f.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }
.ed-size { display: flex; gap: 8px; } .ed-size label { flex: 1; display: flex; flex-direction: column; gap: 4px; } .ed-size .b-field { min-width: 0; }
.ed-toggle { display: flex; align-items: center; justify-content: space-between; }

/* The video editor: the video (cropped and turned by CSS while editing), the filmstrip timeline under it with accent
   trim handles, the kept parts and the playhead, and the saving progress. */
.vs-col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.vs-frame { overflow: hidden; background: var(--br-shade-100); }
.vs-turn { position: absolute; left: 50%; top: 50%; overflow: hidden; transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.vs-turn video { position: absolute; max-width: none; }
.vs-text { position: absolute; white-space: pre; font-family: "Segoe UI Variable Display", "Segoe UI", sans-serif; font-weight: 600; line-height: 1.2; pointer-events: none; }
.vs-text.live { pointer-events: auto; cursor: move; }
.vs-text.is-picked { outline: 1.5px dashed var(--br-accent-primary); outline-offset: 4px; border-radius: var(--br-shape-radius-4); }
.vs-time { flex: none; display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-radius: var(--br-shape-radius-14); background: var(--br-glass-lift); }
.vs-strip { position: relative; flex: 1; height: 52px; border-radius: var(--br-shape-radius-8); cursor: pointer; touch-action: none; }
.vs-frames { position: absolute; inset: 0; display: flex; border-radius: var(--br-shape-radius-8); overflow: hidden; background: var(--br-shade-40); filter: brightness(0.45) saturate(0.6); }
.vs-frames canvas { flex: 1; min-width: 0; height: 100%; object-fit: cover; }
.vs-part { position: absolute; top: 0; bottom: 0; overflow: hidden; border-radius: var(--br-shape-radius-6); box-shadow: inset 0 0 0 2px var(--br-accent-primary); backdrop-filter: brightness(2.2) saturate(1.6); }
.vs-part.is-picked { box-shadow: inset 0 0 0 2px var(--br-tint-100), inset 0 0 18px rgba(var(--br-accent-primary-rgb), 0.9); }
.vs-handle { position: absolute; top: -4px; bottom: -4px; width: 12px; margin-left: -6px; border-radius: var(--br-shape-radius-4); cursor: ew-resize; z-index: 2;
  background: var(--br-accent-primary); box-shadow: 0 2px 6px var(--br-shade-35); }
.vs-head { position: absolute; top: -8px; bottom: -8px; width: 2px; margin-left: -1px; background: var(--br-tint-100); border-radius: var(--br-shape-radius-1); z-index: 3; pointer-events: none; box-shadow: 0 0 6px var(--br-shade-50); }
.vs-saving { position: absolute; left: 50%; bottom: 20px; transform: translateX(-50%); display: flex; align-items: center; gap: 12px; padding: 8px 12px 8px 16px; border-radius: var(--br-shape-radius-14); z-index: 4; }
.vs-bar { width: 180px; height: 6px; border-radius: var(--br-shape-radius-3); background: var(--br-glass-lift-strong); overflow: hidden; }
.vs-bar > i { display: block; height: 100%; background: var(--br-accent-primary); transition: width var(--br-motion-progress) linear; }

/* The PDF editor: draggable page thumbnails, the page with its marks (SVG), text, notes and form fields on top, the
   signature pad and Combine's list in the inspector. */
.pe-thumbs { border-radius: var(--br-shape-radius-14); }
.pe-thumbs .th.is-dragging { opacity: 0.4; }
.pe-thumbs .th > span { transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.pe-area { overflow: auto; align-items: center; justify-content: center; }
.pe-sheet { position: relative; flex: none; background: var(--br-tint-100); box-shadow: 0 8px 24px var(--br-shade-35); transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.pe-sheet > img { position: absolute; inset: 0; width: 100%; height: 100%; user-select: none; pointer-events: none; }
.pe-marks { position: absolute; inset: 0; touch-action: none; }
.pe-marks.tool-select { cursor: default; } .pe-marks.tool-comment, .pe-marks.tool-sign { cursor: copy; }
.pe-marks.tool-edit, .pe-marks.tool-highlight, .pe-marks.tool-draw, .pe-marks.tool-shapes, .pe-marks.tool-redact { cursor: crosshair; }
.pe-marks .pe-picked { filter: drop-shadow(0 0 2px var(--br-accent-primary)) drop-shadow(0 0 2px var(--br-accent-primary)); }
.pe-text { position: absolute; white-space: pre; pointer-events: none; font-family: "Segoe UI", sans-serif; line-height: 1.2; }
.pe-text.sig { font-family: "Segoe Script", cursive; }
.pe-text.is-picked { outline: 1.5px dashed var(--br-accent-primary); outline-offset: 3px; }
.pe-note { position: absolute; width: 22px; height: 22px; margin: -2px; display: grid; place-items: center; font-size: 14px; cursor: pointer; border-radius: var(--br-shape-radius-6); background: var(--br-pdf-note); box-shadow: 0 2px 6px var(--br-shade-30); }
.pe-note.is-picked { box-shadow: 0 0 0 2px var(--br-accent-primary), 0 2px 6px var(--br-shade-30); }
.pe-field { position: absolute; box-sizing: border-box; margin: 0; padding: 0 4px; border: 1px solid var(--br-pdf-field-edge); border-radius: var(--br-shape-radius-2); background: var(--br-pdf-field-fill); color: var(--br-pdf-field-text); font-family: "Segoe UI", sans-serif; outline: none; resize: none; }
.pe-field:focus { border-color: var(--br-accent-primary); background: rgba(var(--br-accent-primary-rgb), 0.12); }
input[type="checkbox"].pe-field { padding: 0; accent-color: var(--br-accent-primary); }
.pe-pad { width: 100%; height: 96px; border-radius: var(--br-shape-radius-10); background: var(--br-tint-100); touch-action: none; cursor: crosshair; box-shadow: inset 0 0 0 1px var(--br-shade-12); }
.pe-combine { display: flex; flex-direction: column; gap: 8px; }
.pe-combine .ed-toggle > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Games (boards GamesRow, GamesGrid, GamesDetails): the hero info over the hero backdrop (drawn into the wallpaper by
   the host), the library bar, the shelf or grid of 2:3 covers, Details. Covers, title, buttons and bar share one
   left edge. */
.g-page { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 16px; }
/* Over a full-screen hero: a scrim darkens the bottom and left, where the details, buttons and covers sit. */
.g-page.row::before { content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(0deg, var(--br-deep-82) 0%, var(--br-deep-45) 38%, transparent 62%), linear-gradient(90deg, var(--br-deep-55) 0%, transparent 45%); }
.g-hero { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.g-badges { display: flex; gap: 8px; }
.b-badge.warn { background: var(--br-badge-warning-fill); color: var(--br-badge-warning-text); }
.on-bright .b-badge.warn, .on-bright.b-badge.warn { color: var(--br-bright-state-warning); }
.g-title { margin: 4px 0 0; font: 700 56px/1.05 var(--br-font-display); letter-spacing: -0.5px; text-shadow: 0 2px 18px var(--br-shade-45); }
.g-logo { display: block; max-width: 480px; max-height: 130px; margin: 6px 0 2px; object-fit: contain; object-position: left center; filter: drop-shadow(0 4px 16px var(--br-shade-50)); }
.g-stats { display: flex; gap: 32px; margin: 8px 0 6px; }
.g-stats dt { font-size: 12px; opacity: 0.8; }
.g-stats dd { margin: 2px 0 0; font: 600 20px/1.2 var(--br-font-mono); text-shadow: 0 1px 10px var(--br-shade-50); }
.g-actions { display: flex; gap: 8px; }
.g-actions .b-btn { height: 60px; font-size: 18px; border-radius: var(--br-shape-radius-16); }
.g-actions .g-play { padding: 0 36px; box-shadow: 0 0 24px rgba(var(--br-accent-primary-rgb), 0.55), var(--br-shadow-edge-light); }
.g-actions .g-big { padding: 0 30px; }
.g-actions .b-icon-btn.g-big { width: 60px; padding: 0; }
.g-star.on { color: var(--br-games-star); }
.g-bar { display: flex; align-items: center; }
/* Row: the hero, the Recent / Favourites / A-Z switch and the search field share one grid. Its first column is exactly as wide as the
   buttons, and the logo (or a wrapped title), the stats and the switch all fill that width. The bar and the row sit
   at the bottom whether or not a game is shown. */
/* The hero's column is exactly the button row's width (Play 170 + Details 190 + star 60 + gaps), with or without a game. */
.g-page.row > .g-top { margin-top: auto; display: grid; grid-template-columns: 436px 1fr; row-gap: 16px; align-items: center; }
.g-top > .g-hero { grid-column: 1; }
.g-top > .g-barL { grid-column: 1; grid-row: 2; }
.g-top > .g-barL, .g-top > .g-barR { display: flex; align-items: center; }
.g-page.grid .g-shelf { scrollbar-gutter: stable; }   /* the scrollbar's room is kept with few games too, so the covers never resize on a filter */   /* no text baseline: the row is the same height whichever filter is chosen */
.g-top > .g-barR { grid-column: 2; grid-row: 2; justify-self: end; }
.g-top .g-logo, .g-top .g-title, .g-top .g-stats, .g-barL .b-seg { width: 0; min-width: 100%; }   /* they take the column's width, they never set it */
/* The title block is always the same height (and the badge row is always there), so changing the filter or the game never moves
   the buttons: the logo fits it, a title wraps to at most three lines. */
.g-top .g-badges { min-height: 20px; }
.g-top .g-logo { max-width: none; max-height: none; height: 132px; object-fit: contain; object-position: left bottom; }
.g-top .g-title { height: 132px; margin: 0; display: flex; align-items: flex-end; font-size: 40px; line-height: 1.1; overflow-wrap: anywhere; }
.g-top .g-title > span { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
.g-top .g-stats { justify-content: space-between; flex-wrap: wrap; gap: 12px 24px; }
.g-shelf { flex: 1; min-height: 0; }   /* it is a .b-scroll.tiles: the catch-all .b-scroll padding rule must not shrink its gutters */
/* The row and the grid keep a gutter as deep as a grown cover and its shadow (cancelled by a negative margin), so nothing is cut off. */
.g-page.row .g-shelf { flex: none; min-height: calc(var(--cover-w, 250px) * 1.5 + 90px); display: flex; gap: 28px; overflow-x: auto; overflow-y: hidden; padding: 32px 16px 44px; margin: -16px -16px 0; align-items: flex-start; }   /* top: clear of the library bar; bottom: inside the window (the page clips there) */
/* The scrollbar's ends sit on the page's content edges (the shelf reaches 32px past them for the grown covers), and it ends where the page does,
   16px above the window's edge, like every panel in Bridge. */
.g-page.row .g-shelf::-webkit-scrollbar-track { margin: 0 16px; }
/* On the row the scrollbar is always there (not only while the pointer is over the row or it's scrolling): it shows how
   far along your games you are. */
.b-app .g-page.row .g-shelf:not(:hover):not(.is-scrolling)::-webkit-scrollbar-thumb { background-color: var(--br-tint-28); }
:root[data-input=pad] .g-page.row .g-shelf::-webkit-scrollbar { display: none; }   /* the scrollbar is for mouse and keyboard; a controller moves along the row */
.g-page.grid .g-shelf { display: grid; grid-template-columns: repeat(var(--grid-cols, auto-fill), var(--grid-w, var(--cover-w, 250px))); justify-content: space-between; gap: 20px; align-content: start; overflow-y: auto; padding: 28px 28px 36px; margin: -20px -28px -28px; }
.g-gridbody { flex: 1; min-height: 0; display: flex; gap: 16px; position: relative; }
/* The grid is its own glass panel, with the library bar inside it. */
.g-gridpanel { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; padding: 16px; gap: 12px; }
.g-page.grid .g-gridpanel .g-shelf { flex: 1; min-height: 0; margin: -8px -16px -16px; padding: 24px 28px 28px; }
.g-cover { position: relative; flex: none; width: var(--cover-w, 250px); height: calc(var(--cover-w, 250px) * 1.5);   /* exactly the 2:3 cover shape */ border-radius: var(--br-shape-radius-14); overflow: hidden; cursor: pointer;
  background: center / cover no-repeat; box-shadow: var(--br-shadow-glass); transform-origin: center; transition: transform var(--br-motion-panel) var(--br-motion-ease-spring), box-shadow var(--br-motion-move) var(--br-motion-ease-standard); }
.g-page.grid .g-cover { transform-origin: center; }   /* the size is the Settings cover size, as in the row */
/* Rows are as tall as the covers, set outright (3/2 of the width): never measured, so never cut or overlapping. */
.g-page.grid .g-shelf { grid-auto-rows: calc(var(--grid-w, var(--cover-w, 250px)) * 1.5); }   /* --grid-w: the cover width that fills the row (set by the page) */
.g-page.grid .g-cover { width: var(--grid-w, var(--cover-w, 250px)); height: calc(var(--grid-w, var(--cover-w, 250px)) * 1.5); }
/* In the row the selected cover grows from its middle; only the first and last games grow toward the edge of the screen. */
.g-page.row .g-cover:first-child { transform-origin: left center; }
.g-page.row .g-cover:last-child { transform-origin: right center; }
.g-page.row .g-cover:only-child { transform-origin: left center; }   /* a lone cover is the first and the last: it stays on the page's left margin like the first cover, growing to the right */
/* Inside Bridge the page ends at the edge of Bridge's content, so the first cover's selected edge needs a little room to show. */
.g-in-bridge .g-page.row .g-shelf { padding-left: 20px; }
.g-cover.is-selected { transform: scale(1.08); z-index: 1; box-shadow: var(--br-selected-edge); }   /* no drop shadow: it can't be seen on the dark backing, so it takes no room */
.g-page.grid .g-cover.is-selected { transform: scale(1.04); }
.g-cover > .b-badge { position: absolute; left: 10px; top: 10px; }
.g-cover > .nm { position: absolute; left: 14px; right: 14px; bottom: 14px; font: 650 18px/1.25 var(--br-font-ui); text-shadow: 0 1px 8px var(--br-shade-60); }
.g-hover { position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column; gap: 8px; padding: 48px 12px 12px; opacity: 0;
  background: linear-gradient(transparent, var(--br-shade-78)); color: var(--br-tint-100); transition: opacity var(--br-motion-press) var(--br-motion-ease-standard); }
.g-hover > b { font: 650 16px/1.25 var(--br-font-ui); }
.g-hover > div { display: flex; gap: 6px; }
.g-page.grid .g-cover:hover .g-hover { opacity: 1; }
.g-page.grid .g-cover:hover > .nm { opacity: 0; }
/* In the grid, any highlighted game shows its name and buttons (FIXES #66): pointed at, controller focus, and the
   selected one. The row has no overlay on its covers: the hero above shows the game and its buttons (Nov 8). */
.g-page.grid .g-cover.is-pad-focus .g-hover, .g-page.grid .g-cover.is-selected .g-hover { opacity: 1; }
.g-page.grid .g-cover.is-pad-focus > .nm, .g-page.grid .g-cover.is-selected > .nm { opacity: 0; }
/* Nothing to show: a quiet message where the covers would be, as tall as a cover so nothing around it moves. */
.g-empty { flex: none; height: calc(var(--cover-w, 250px) * 1.5); display: flex; flex-direction: column; justify-content: center; gap: 8px; padding: 0 4px; }
.g-empty b { font: 650 22px/1.2 var(--br-font-display); }
.g-empty span { font-size: 16px; }
.g-page.grid .g-empty { grid-column: 1 / -1; height: auto; padding: 24px 4px; }
.g-modal { position: fixed; inset: 0; z-index: 12; display: grid; place-items: center; background: var(--br-surface-scrim); }
.g-details { width: 580px; }
.g-dtop { display: flex; gap: 20px; }
.g-dcover { flex: none; width: 160px; aspect-ratio: 2 / 3; border-radius: var(--br-shape-radius-12); background: center / cover no-repeat; box-shadow: var(--br-shadow-glass); }
.g-dinfo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 10px; }
.g-dinfo h2 { margin: 0; font: 700 28px/1.15 var(--br-font-display); }
.g-dinfo dd { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Games: a running game's hero buttons, Change art (board GamesChangeArt). */
.g-actions .g-running { pointer-events: none; }
/* the two buttons keep one size whatever they say (Play/Running, Details/Close game) */
.g-actions .g-slot1 { width: 170px; padding: 0; justify-content: center; }
.g-actions .g-slot2 { width: 190px; padding: 0; justify-content: center; }
.g-art { width: 760px; max-height: calc(100vh - 120px); }
.g-arthead { display: flex; align-items: center; gap: 12px; font-size: 18px; }
.g-artgrid { display: grid; grid-template-columns: repeat(6, 1fr); gap: 12px; max-height: 400px; min-height: 160px; overflow-y: auto; padding: 4px; align-content: start; }
.g-artgrid.hero { grid-template-columns: repeat(2, 1fr); }
.g-artgrid.logo { grid-template-columns: repeat(3, 1fr); }
.g-artitem { all: unset; cursor: pointer; aspect-ratio: 2 / 3; border-radius: var(--br-shape-radius-10); background: var(--br-shade-25) center / cover no-repeat; box-shadow: var(--br-shadow-glass); transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.g-artgrid.hero .g-artitem { aspect-ratio: 96 / 31; }
.g-artgrid.logo .g-artitem { aspect-ratio: 2 / 1; background-size: contain; background-color: var(--br-shade-35); }
.g-artitem.is-selected { transform: scale(1.04); box-shadow: var(--br-selected-edge); }
.g-artkey { display: flex; flex-direction: column; gap: 12px; padding: 8px 0; }

/* Home and its results (board HomeSearch): the 58px field a little above the middle, at most 640px; results 8px below,
   the field's width, at most 340px tall, in groups. Shared by Overview's search. */
/* Home's search rests in the centre of the screen (Home.tsx moves it there from the top) and rises as you type. */
.h-home { flex: 1; display: flex; justify-content: center; padding-top: 0; }
.h-box { position: relative; width: 100%; max-width: 640px; height: 58px; }
.h-box.is-placed, .nt-search { transition: transform var(--br-motion-panel) var(--br-motion-ease-standard); }
.h-results { position: absolute; left: 0; right: 0; top: calc(100% + 8px); z-index: 5; padding: 8px; box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.h-scroll { max-height: 324px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.h-group { padding: 10px 12px 4px; }
.h-row { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 6px 12px; border-radius: var(--br-shape-radius-12); cursor: pointer; }
.h-row.game { min-height: 56px; }
.h-row.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }
.h-row .h-cover { flex: none; width: 28px; height: 42px; border-radius: var(--br-shape-radius-6); background: var(--br-shade-25) center / cover no-repeat; }
.h-row .h-img { flex: none; width: 22px; height: 22px; object-fit: contain; border-radius: var(--br-shape-radius-5); }
.h-row .h-ico { flex: none; width: 22px; display: grid; place-items: center; opacity: 0.85; }
.h-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.h-text b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.h-text small { font-size: 12px; opacity: 0.75; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.h-action { flex: none; font-size: 12px; opacity: 0.7; }

/* Overview (boards Overview, OverviewBackground, AllApps): search at the top, window cards grouped by screen, the dock
   at the bottom centre; the live pictures are drawn by the host into each card's frame. */
.ov { position: fixed; inset: 0; z-index: 9; display: flex; flex-direction: column; align-items: center; padding: 24px 48px 0; gap: 18px; animation: ov-in var(--br-motion-panel) var(--br-motion-ease-enter); }
@keyframes ov-in { from { opacity: 0; transform: scale(0.98); } }
.ov-search { position: relative; width: 480px; max-width: 100%; height: 46px; flex: none; }
.ov-cards { flex: 1; min-height: 0; width: 100%; overflow-y: auto; display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 8px 0 24px; }
.ov-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 28px; }
.ov-display { margin-top: 6px; }
.ov-card { width: calc(320px * var(--tile-scale, 1)); display: flex; flex-direction: column; gap: 8px; cursor: pointer; border-radius: var(--br-shape-radius-16); padding: 6px; transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.ov-card:hover, .ov-card:focus-visible { transform: scale(1.04); outline: none; box-shadow: var(--br-highlight-edge); }
.ov-head { display: flex; align-items: center; gap: 10px; height: 32px; padding: 0 4px; }
.ov-head img { width: 24px; height: 24px; border-radius: var(--br-shape-radius-6); }
.ov-head b { flex: 1; min-width: 0; font: 650 16px/20px var(--br-font-ui); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-shadow: 0 1px 8px var(--br-shade-45); }
.ov-mark { width: 24px; height: 24px; display: grid; place-items: center; }
.ov-x { opacity: 0; transition: opacity var(--br-motion-press) var(--br-motion-ease-standard); }
.ov-card:hover .ov-x, .ov-card:focus-within .ov-x { opacity: 1; }
.ov-thumb { aspect-ratio: 16 / 10; border-radius: var(--br-shape-radius-14); display: grid; place-items: center; box-shadow: var(--br-shadow-edge-light), var(--br-shadow-glass); }
.ov-self span { font: 650 18px/1 var(--br-font-display); opacity: 0.85; }
.ov-title { padding: 0 6px; font-size: 12px; opacity: 0.7; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ov-none { padding: 24px; }
.ov-dock { flex: none; display: flex; align-items: center; gap: 10px; padding: 12px 16px; margin-top: auto; margin-bottom: 24px; border-radius: var(--br-shape-radius-20); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.ov-app { all: unset; width: 48px; height: 48px; display: grid; place-items: center; border-radius: var(--br-shape-radius-14); cursor: pointer; transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.ov-app:hover, .ov-app:focus-visible { transform: scale(1.12); box-shadow: var(--br-highlight-edge); }
.ov-app img { width: 36px; height: 36px; object-fit: contain; }
.ov-app span { font: 700 20px/1 var(--br-font-display); }
.ov-sep { width: 1px; height: 32px; background: var(--br-glass-edge); }
.ov-dockbtn { width: 48px; height: 48px; }
.ov-bgwrap { position: relative; }
.ov-count { position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--br-shape-radius-9); display: grid; place-items: center; font-size: 11px; background: var(--br-glass-lift-strong); box-shadow: var(--br-shadow-edge-light); }
.ov-bgpanel { position: fixed; bottom: 112px; left: calc(50% + 40px); width: 300px; padding: 12px; display: flex; flex-direction: column; gap: 4px; z-index: 10; box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.ov-bgrow { display: flex; align-items: center; gap: 10px; height: 44px; padding: 0 6px 0 10px; border-radius: var(--br-shape-radius-12); cursor: pointer; }
.ov-bgrow:hover { box-shadow: var(--br-highlight-edge); }
.ov-bgrow img { width: 22px; height: 22px; }
.ov-bgrow span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* All apps in the open apps' place (FIXES #90), straight on the backdrop like GNOME's app grid. */
.ov-apps { flex: 1; min-height: 0; width: min(1240px, 100%); overflow-y: auto; overflow-x: hidden; padding: 8px 0 24px; animation: ov-apps-in var(--br-motion-panel) var(--br-motion-ease-enter); }
@keyframes ov-apps-in { from { opacity: 0; transform: scale(0.96); } }
.ov-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 12px 8px; padding: 4px; }
.ov-gapp { all: unset; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 12px 6px; border-radius: var(--br-shape-radius-14); cursor: pointer; text-align: center; }
.ov-gapp:hover, .ov-gapp:focus-visible { box-shadow: var(--br-highlight-edge); }
.ov-gapp img, .ov-gapp .ov-letter { width: 64px; height: 64px; }
.ov-gapp img { object-fit: contain; }   /* every app's icon at 128px from the shell, shown the same size (FIXES #50) */
.ov-gapp .ov-letter { display: grid; place-items: center; border-radius: var(--br-shape-radius-12); font: 700 20px/1 var(--br-font-display); background: var(--br-glass-lift-strong); }
.ov-gapp small { font-size: 13px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-shadow: 0 1px 3px var(--br-shade-45); }

/* The start screen (boards StartLoading, StartClock): the logo above the name, centred and bigger while loading (the
   mark traces on, then pulses until everything is ready; at least 2 s), then gliding up to its place above the frosted clock. */
.st { position: fixed; inset: 0; z-index: 30; display: grid; place-items: center; transition: opacity var(--br-start-exit) var(--br-motion-ease-exit); }
.st.leaving { opacity: 0; }
.st-stack { position: relative; display: flex; flex-direction: column; align-items: center; gap: 14px; }
.st-brand { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.st:not(.loading) .st-brand { transition: transform var(--br-start-glide) var(--br-motion-ease-standard); }   /* the glide up to the clock, not at the first paint */
.st.loading .st-brand { transform: translateY(var(--dy, 0px)) scale(2.2); }
/* Clearly visible on any wallpaper (the loading logo was hard to see): a lightened accent, a dark shadow under
   it, and a soft dark pool behind it while loading. */
.st::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(closest-side at 50% 50%, var(--br-shade-50), transparent); background-size: 900px 900px; background-repeat: no-repeat; background-position: center; opacity: 0; transition: opacity var(--br-start-fade) var(--br-motion-ease-standard); }
.st.loading::before { opacity: 1; }
.st-brand svg { width: 84px; height: 59px; overflow: visible; filter: drop-shadow(0 2px 8px var(--br-shade-55)); }
.st-brand path { stroke: color-mix(in srgb, var(--br-accent-primary) 60%, var(--br-tint-100)); stroke-dasharray: 100; stroke-dashoffset: 100; animation: st-draw var(--br-start-draw) var(--br-motion-ease-standard) forwards; }
.st-brand rect { fill: color-mix(in srgb, var(--br-accent-primary) 60%, var(--br-tint-100)); transform-origin: center; transform: scaleX(0); animation: st-deck var(--br-start-fade) var(--br-start-deck-delay) var(--br-motion-ease-standard) forwards; }
.st.loading .st-brand svg { animation: st-pulse var(--br-start-pulse) var(--br-start-pulse-delay) ease-in-out infinite; }
@keyframes st-draw { to { stroke-dashoffset: 0; } }
@keyframes st-deck { to { transform: scaleX(1); } }
@keyframes st-pulse { 50% { filter: drop-shadow(0 2px 8px var(--br-shade-55)) drop-shadow(0 0 12px rgba(var(--br-accent-primary-rgb), 0.9)); } }
.st-word { font: 400 24px/1 var(--br-font-wordmark); letter-spacing: 5px; opacity: 0; animation: st-fade var(--br-start-fade) var(--br-start-word-delay) forwards; text-shadow: 0 1px 10px var(--br-shade-35); }
@keyframes st-fade { to { opacity: 1; } }
.st-under { display: flex; flex-direction: column; align-items: center; gap: 14px; transition: opacity var(--br-start-fade) var(--br-start-under-delay) var(--br-motion-ease-standard); }
.st.loading .st-under { opacity: 0; transition: none; }
.st-date { font: 500 22px/1.2 var(--br-font-ui); letter-spacing: normal; word-spacing: normal; opacity: 0.85; text-shadow: 0 1px 10px var(--br-shade-40); }

/* Controller and keyboard focus: looks like hover (the highlight edge alone: no fill, no glow inside; decisions 146, 151). The on-screen keyboard
   (board Keyboard): 920px of glass at the bottom centre, three suggestions over one 11-column grid. */
.is-pad-focus { outline: none !important; box-shadow: var(--br-highlight-edge); border-radius: var(--br-shape-radius); }
.g-cover.is-pad-focus, .ov-card.is-pad-focus, .ov-app.is-pad-focus { transform: scale(1.06); }
/* A primary (accent) button with controller focus (FIXES #64): the accent edge would vanish on it, so a white ring over a
   thin dark gap, and it grows a little, readable on any accent colour. */
.b-btn.primary.is-pad-focus { background-color: var(--br-accent-primary); box-shadow: 0 0 0 2px var(--br-focus-pad-gap), 0 0 0 4px var(--br-tint-100), var(--br-shadow-lift); transform: scale(1.05); }
.osk { position: fixed; left: 50%; bottom: 16px; z-index: 28; width: 920px; max-width: calc(100vw - 32px); transform: translateX(-50%); padding: 10px; display: flex; flex-direction: column; gap: 6px; box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.osk-sug { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.osk-row { display: grid; grid-template-columns: repeat(11, 1fr); gap: 6px; }
.osk-key { all: unset; height: 52px; border-radius: var(--br-shape-radius-12); display: grid; place-items: center; font: 500 18px/1 var(--br-font-ui); background: var(--br-glass-lift); cursor: pointer; box-shadow: inset 0 0 0 1px var(--br-glass-edge); }
.osk-sug .osk-key { height: 42px; font-size: 16px; }
.osk-key:hover { box-shadow: var(--br-highlight-edge); }
.osk-key.is-selected, .osk-key.is-on { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }
.osk-key.is-pad { background: var(--br-glass-lift-strong); box-shadow: var(--br-selected-edge); transform: scale(1.05); }
.osk-key:disabled { opacity: 0.35; }
.h-home, .ov-cards { padding-bottom: var(--osk-room, 0px); }

/* Settings (board Settings): the sidebar (Find a setting, sections) and the section panel. Groups are open while the
   section fits; only when it doesn't are just enough of them folded. */
.se-page { flex: 1; min-height: 0; display: flex; gap: 16px; }
.se-side { width: 300px; flex: none; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.se-list { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 2px; }
.se-list .txt { display: flex; flex-direction: column; min-width: 0; }
.se-list .txt small { font-size: 12px; }
.se-main { flex: 0 1 560px; min-width: 0; padding: 20px 16px 16px; display: flex; flex-direction: column; gap: 12px; }   /* one card wide (FIXES #102) */
.se-title { margin: 0 16px 4px; font: 700 28px/1.2 var(--br-font-display); }
.se-groups { flex: 1; min-height: 0; }
/* The groups: cards in one stack, with room for their shadows inside the scrolling area. */
.se-cols { display: flex; flex-direction: column; gap: 18px; padding: 6px 12px 28px; }
.se-groups.b-scroll { padding-bottom: calc(8px + var(--osk-room, 0px)) !important; }
/* A group: a card exactly like the new tab's search bar (FIXES #98, #101, #102): the panel's glass shows through it (no
   tint or blur of its own), with that bar's clear edge, edge light and shadow; its name at the top, lines between rows. */
.se-group { flex: none; }
.se-rows-in { display: flex; flex-direction: column; padding: 4px 0; border-radius: var(--br-shape-radius); }
.se-page .se-rows-in { background: transparent; border: 1px solid var(--br-tint-26); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-glass); }
.se-ctitle { padding: 12px var(--br-space-4) 2px; font: 600 12px/1.2 var(--br-font-ui); letter-spacing: 0.06em; text-transform: uppercase; color: var(--br-text-secondary); }
.se-rows-in > .b-srow { position: relative; }
.se-rows-in > .b-srow + .b-srow::before, .se-rows-in > .b-srow + :not(.b-srow)::before { content: ''; position: absolute; left: var(--br-space-4); right: var(--br-space-4); top: 0; height: 1px; background: var(--br-glass-edge); }
.se-rows-in > .b-srow + :not(.b-srow) { position: relative; }
/* Rows aren't buttons (their controls are): no hover tint, no hand. Nothing in Settings grows when selected, so
   nothing reaches past the panel's edges. */
.se-page .b-srow { cursor: default; flex-wrap: wrap; row-gap: 8px; }
.se-page .b-srow > .txt { min-width: 220px; }
.se-page .b-srow > :last-child:not(.txt) { margin-left: auto; max-width: 100%; }
.se-page .b-item.is-selected, .se-page .b-srow.is-selected, .se-page .b-chip.is-selected { transform: none; }
/* A set of on/off buttons (Game overlay › Shows, FIXES #107): ordinary small buttons, as wide as their words. */
.se-toggles { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 8px; }   /* equal widths, filling the row */
.b-srow .se-toggles .b-btn:not(.b-icon-btn) { min-width: 0; padding-inline: 6px; }
.se-page .b-glass .se-toggles .b-btn.is-on { color: var(--br-text-primary); background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }   /* on: the selected look, like a selected tab */
.se-page .b-glass .se-toggles .b-btn:not(.is-on) { color: var(--br-text-secondary); }
/* A wide control (a row of chips, a long switcher) sits under its title, full width (FIXES #106). */
.se-page .b-srow.se-wide { flex-direction: column; align-items: stretch; padding-block: 12px; }
.se-page .b-srow.se-wide > :last-child:not(.txt) { margin-left: 0; }
.se-page .b-srow.se-wide .b-seg { display: grid; width: 100%; }
.se-page .b-srow.se-wide .b-seg > span { padding-inline: 8px; }
/* A flyout's panel shown in Settings: one scroll (the section's), never a list scrolling inside it. */
.se-embed .b-scroll { max-height: none !important; overflow: visible; padding: 0 !important; margin: 0 !important; }
.se-flash { animation: se-flash var(--br-motion-flash) var(--br-motion-ease-standard); }
@keyframes se-flash { 0%, 60% { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); } }
.se-slider { display: flex; align-items: center; gap: 12px; width: 280px; }
.se-slider .b-slider, .se-slider > :first-child { flex: 1; }
.se-slider .b-num { min-width: 40px; text-align: right; }
.se-swatches { display: flex; gap: 10px; }
.se-swatches .b-swatch { all: unset; width: 26px; height: 26px; border-radius: 50%; cursor: pointer; box-shadow: inset 0 0 0 1px var(--br-tint-30); }
/* Settings › Appearance › Custom: the themes of the library, one card each (its two accents and its name). */
.se-themes { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: var(--br-space-2); }
.se-theme { all: unset; box-sizing: border-box; cursor: pointer; min-width: 0; display: flex; flex-direction: column; gap: var(--br-space-2); padding: var(--br-space-3); border-radius: var(--br-shape-radius);
  background: var(--br-glass-inset); box-shadow: inset 0 0 0 1px var(--br-glass-edge); font: 600 14px/20px var(--br-font-ui); transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.se-theme .dots { display: flex; gap: var(--br-space-1); }
.se-theme .dots i { width: 18px; height: 18px; border-radius: 50%; box-shadow: inset 0 0 0 1px var(--br-tint-18); }
.se-theme .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.se-theme.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); transform: scale(var(--br-motion-select-scale)); }
.se-swatches .b-swatch.is-selected { box-shadow: 0 0 0 2px var(--br-glass-tint), 0 0 0 4px var(--br-tint-100); }
.se-swatches.is-off { opacity: 0.4; pointer-events: none; }
.se-pad { padding: 8px 16px 12px; }
.se-kv { padding: 8px 16px 12px; }
.se-rows-in > .se-pad, .se-rows-in > .se-kv, .se-rows-in > .se-drives { padding: 14px 16px; }
.se-log pre { margin: 0 0 10px; max-height: 320px; overflow: auto; padding: 12px; border-radius: var(--br-shape-radius-12); background: var(--br-shade-28); font: 12px/1.5 var(--br-font-mono); white-space: pre-wrap; }
.se-buttons { display: flex; gap: 8px; }
.se-stack { display: flex; flex-direction: column; gap: 10px; }   /* fields one under another, full width (FIXES #113) */
.b-kbd { font: 600 11px/1 var(--br-font-mono); padding: 4px 6px; border-radius: var(--br-shape-radius-6); background: var(--br-glass-lift); opacity: 0.8; }

/* Settings › Wallpaper, Storage and the flyout panels shown inside Settings. */
.se-walls { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(180px * var(--tile-scale, 1)), 1fr)); gap: 12px; }
.se-wall { all: unset; position: relative; aspect-ratio: 16 / 10; border-radius: var(--br-shape-radius-12); cursor: pointer; background: var(--br-shade-25) center / cover no-repeat; box-shadow: var(--br-shadow-glass); transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.se-wall:hover { transform: scale(1.03); box-shadow: var(--br-highlight-edge), var(--br-shadow-glass); }
.se-wall.is-selected { box-shadow: var(--br-selected-edge), var(--br-shadow-glass); }
.se-wall .b-badge { position: absolute; left: 8px; top: 8px; }
/* Delete: shows on hover (or keyboard focus), top right; red on its own hover. */
.se-wall .se-wall-x { position: absolute; right: 8px; top: 8px; opacity: 0; transform: scale(0.9); transition: opacity var(--br-motion-move) var(--br-motion-ease-standard), transform var(--br-motion-move) var(--br-motion-ease-standard);
  background: var(--br-smoke-62); }
.se-wall:hover .se-wall-x, .se-wall:focus-within .se-wall-x, .se-wall .se-wall-x:focus-visible { opacity: 1; transform: none; }
.se-wall .se-wall-x:hover { color: var(--br-state-danger); }
/* Bridge | Yours over the tiles; Bridge's own tiles carry their name along the bottom, on a shade that keeps it readable. */
.se-walls-head { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.se-wall-name { position: absolute; left: 0; right: 0; bottom: 0; padding: 18px 10px 8px; border-radius: 0 0 var(--br-shape-radius-12) var(--br-shape-radius-12); font-weight: 600; font-size: 13px; color: var(--br-tint-100);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; background: linear-gradient(180deg, transparent, var(--br-deep-70)); pointer-events: none; }
.se-walls-empty { padding: 24px 4px 4px; }
.se-embed { padding: 0 4px; }
.se-embed .se-sublabel { padding: 12px 12px 4px; }
.se-slider.wide { width: 380px; gap: 8px; }
.se-slider.wide > :first-child { flex: none; }
.se-slider.wide > :nth-child(2) { flex: 1; }
.se-embed .b-srow { padding-inline: 12px; }
.se-drives { display: flex; flex-direction: column; gap: 14px; }
.se-drivehead { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.se-bar { height: 8px; border-radius: var(--br-shape-radius-4); background: var(--br-glass-lift-strong); overflow: hidden; }
.se-bar > i { display: block; height: 100%; background: var(--br-accent-primary); }

/* Settings › Games, Tabs: list lines, field rows, the Add launcher dialog (board SettingsAddLauncher). */
.se-line { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 4px 8px; border-radius: var(--br-shape-radius-10); }
.se-line > .b-num { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.se-drag { cursor: grab; }
.se-grip { opacity: 0.5; letter-spacing: -3px; }
.se-frow { display: flex; gap: 8px; align-items: center; }
.se-flabel { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--br-text-secondary); }
.se-dialog { width: 560px; max-height: calc(100vh - 120px); overflow-y: auto; }
.se-dtitle { font: 650 18px/1.3 var(--br-font-ui); }

/* The Server tab (boards Server, ServerAdd). */
.sv-page { flex: 1; min-height: 0; display: flex; gap: 16px; }
.sv-side { width: 400px; flex: none; padding: 14px; display: flex; flex-direction: column; gap: 12px; }
.sv-main { flex: 1; min-width: 0; padding: 14px; display: flex; flex-direction: column; gap: 10px; }
.sv-none { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center; }
.sv-none b { font: 650 22px/1.2 var(--br-font-display); }
.sv-head { display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 0 6px; font-size: 18px; }
.sv-head .b-muted { font-size: 14px; }
.sv-list { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; }
.sv-card { padding: 12px 14px; border-radius: var(--br-shape-radius-14); background: var(--br-glass-lift); display: flex; flex-direction: column; gap: 10px; cursor: pointer; }
.sv-card.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }
.sv-top { display: flex; align-items: center; gap: 8px; }
.sv-top .b-muted { font-size: 12px; }
.sv-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--br-text-secondary); flex: none; }
.sv-dot.running { background: var(--br-server-running); box-shadow: 0 0 8px var(--br-server-running-glow); }
.sv-dot.crashed { background: var(--br-server-crashed); }
.sv-buttons { display: flex; align-items: center; gap: 6px; }
.sv-log { flex: 1; min-height: 0; overflow: auto; padding: 12px 14px; border-radius: var(--br-shape-radius-12); background: var(--br-shade-30); font: 13px/1.6 var(--br-font-mono); white-space: pre-wrap; word-break: break-word; }
.sv-log .t { opacity: 0.5; }
.sv-log .warn { color: var(--br-server-log-warning); }
.sv-log .err { color: var(--br-server-log-error); }
.sv-cmd { display: flex; gap: 8px; }
.sv-apps { display: flex; flex-direction: column; gap: 8px; }
.sv-applist { max-height: 200px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }

/* First-run setup (board Setup): one glass card per step with step dots, Back / Skip / Next. */
.su { position: fixed; inset: 0; z-index: 26; display: grid; place-items: center; }
/* The card is as tall as its step needs (never shorter than 580px), so nothing in it scrolls; only a window too small
   for a step lets that step's body scroll. */
.su-card { width: 800px; min-height: 580px; max-height: calc(100vh - 48px); display: flex; flex-direction: column; gap: 10px; padding: 28px 32px; }
.su-head { display: flex; align-items: center; }
.su-brand { display: flex; align-items: center; gap: 10px; font: 400 16px/1 var(--br-font-wordmark); letter-spacing: 3px; }
.su-brand svg { width: 28px; height: 20px; }
.su-dots { display: flex; gap: 6px; align-items: center; }
.su-dots i { width: 6px; height: 6px; border-radius: var(--br-shape-radius-3); background: var(--br-text-secondary); opacity: 0.6; transition: width var(--br-motion-move) var(--br-motion-ease-standard); }
.su-dots i.on { width: 20px; background: var(--br-text-primary); opacity: 1; }
.su-card h1 { margin: 18px 0 0; font: 700 28px/1.2 var(--br-font-display); }
.su-card p { margin: 0 0 6px; }
.su-body { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; display: flex; flex-direction: column; gap: 10px; }
.su-foot { display: flex; gap: 8px; align-items: center; }
.su-points { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 24px; }
.su-points div { display: flex; flex-direction: column; gap: 2px; }
.su-points b { font-weight: 600; }
.su-points span { font-size: 13px; line-height: 1.4; }
.su-foot .b-btn { min-width: 110px; }
.g-actions .g-stop { background: var(--br-state-danger); color: var(--br-tint-100); box-shadow: 0 0 24px var(--br-games-stop-glow), var(--br-shadow-edge-light); }

/* A page that failed (ui/guard.tsx): a calm message in the page's place. */
.b-guard { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; text-align: center; }
.b-guard b { font: 650 22px/1.2 var(--br-font-display); }
.b-guard .b-btn { margin-top: 8px; }

/* Motion (UI motion guide): selected tabs, chips and the logo grow on the soft spring. */
.b-tab, .b-chip, .b-logo { transition-property: transform, background-color, color, box-shadow; transition-duration: var(--br-motion-panel), var(--br-motion-move), var(--br-motion-move), var(--br-motion-move);
  transition-timing-function: var(--br-motion-ease-spring), var(--br-motion-ease-standard), var(--br-motion-ease-standard), var(--br-motion-ease-standard); }

/* Windows' "Animation effects" off: nothing moves or grows; things only fade, quickly. */
@media (prefers-reduced-motion: reduce) {
  :root { --br-motion-select-scale: 1; --br-motion-move: var(--br-motion-reduced-move); --br-motion-panel: var(--br-motion-reduced-panel); --br-motion-exit: var(--br-motion-reduced-exit); }
  *, *::before, *::after { animation-iteration-count: 1 !important; scroll-behavior: auto !important; }
  .g-cover.is-selected, .b-item.is-selected, .b-srow.is-selected, .st.loading .st-brand { transform: none !important; }
}

/* A surface page held to the window's height scrolls as a whole; what's inside keeps its own height (it never squeezes
   to fit), so the page can always tell the shell how tall it really is. */
.sf-capped > * { flex-shrink: 0; }

/* Small windows (Bridge's smallest is 1100 x 720; with Text size at 140% that is 786 x 514 of room). Nothing is cut:
   the top bar's icons sit closer, side panels narrow, the Games hero gives the covers room, rows let controls shrink. */
.fl-places { width: 280px; padding: 16px 12px; overflow-y: auto; overflow-x: hidden; }
@media (max-width: 1000px) {
  .b-topbar .right { gap: 0; }
  .se-side { width: 230px; }
  .fl-places { width: 220px; }
}
.se-slider, .se-slider.wide { max-width: 100%; }
.se-page .b-srow .b-seg { max-width: 100%; }
.se-page .b-srow .b-seg > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.se-wall.is-selected { box-shadow: var(--br-selected-edge); }
/* Games row in a short window: first the stats go and the logo shrinks, then the logo goes and the buttons get smaller. */
@media (max-height: 820px) {
  .g-page.row .g-top .g-stats { display: none; }
  .g-page.row .g-top .g-logo, .g-page.row .g-top .g-title { height: 84px; font-size: 30px; }
}
@media (max-height: 620px) {
  .g-page.row .g-top .g-logo, .g-page.row .g-top .g-title, .g-page.row .g-top .g-badges { display: none; }
  .g-page.row .g-actions .b-btn { height: 44px; font-size: 16px; border-radius: var(--br-shape-radius-12); }
  .g-page.row .g-actions .b-icon-btn.g-big { width: 44px; }
}

/* The browser's search suggestions (browser/suggest.tsx): a glass list under the field, the same rows as menus. */
.b-suggest-panel { position: absolute; left: 0; right: 0; top: calc(100% + 8px); z-index: 5; padding: 6px; border-radius: var(--br-shape-radius); }
.b-suggest-panel.in-side { background: var(--br-glass-strong); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.b-suggest { display: flex; flex-direction: column; gap: 2px; }
.b-suggest .b-item { height: 40px; cursor: pointer; }
.b-suggest .b-item .txt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.b-suggest .b-item .txt b { font-weight: 600; }

/* Something set up and working (Settings › Games › SteamGridDB key): a quiet green check. */
.se-active { display: inline-flex; align-items: center; gap: 6px; color: var(--br-state-success); font-weight: 600; font-size: 13px; }

/* Narrow windows: what can step aside does, so nothing is cut. The top bar's date (the time stays), then its optional
   System and Tailscale icons; Files' Cut / Copy / Paste buttons (Ctrl+X / C / V and the right-click menu still have them),
   and its Details panel floats over the folder instead of squeezing it. */
.tb-extra { display: contents; }
@media (max-width: 1400px) { .tb-date { display: none; } }
@media (max-width: 900px) { .tb-extra { display: none; } .fl-clip { display: none; } .b-topbar .b-logo > span { display: none; } }
/* The smallest windows: now playing keeps its art (opens Music), play / pause and ×; previous and next go, then the
   Calculator icon, so the top bar's right side always fits (Bridge's smallest window at 140% text is 786px). */
@media (max-width: 900px) { .b-topbar .b-np [aria-label="Previous"], .b-topbar .b-np [aria-label="Next"] { display: none; } }
@media (max-width: 820px) { .b-topbar [aria-label="Calculator"] { display: none; } }
@media (max-width: 1000px) { .b-files > aside.b-panel { position: absolute; right: 0; top: 0; bottom: 0; z-index: 6; box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float) !important; } }

/* Bridge's tooltip (tooltip.ts): a small dark glass label at the cursor; never Windows' own. */
.b-tip { position: fixed; z-index: 100; max-width: 360px; padding: 5px 9px; border-radius: var(--br-shape-radius-8); pointer-events: none;
  background: var(--br-smoke-90); color: var(--br-tooltip-text); font: 500 12px/16px var(--br-font-ui); box-shadow: 0 0 0 1px var(--br-tint-12), 0 4px 12px var(--br-shade-35);
  opacity: 0; transform: translateY(-2px); transition: opacity var(--br-motion-move) var(--br-motion-ease-standard), transform var(--br-motion-move) var(--br-motion-ease-standard); white-space: pre-line; overflow-wrap: anywhere; }
.b-tip.is-shown { opacity: 1; transform: none; }

/* Text files in the viewer: the monospace face on a dark inset well, wrapped, the whole stage. */
.b-vtext { flex: 1; align-self: stretch; margin: 0; padding: 16px 20px; border: 0; border-radius: var(--br-shape-radius-12); background: var(--br-shade-28); color: var(--br-text-primary);
  font: 13px/20px var(--br-font-mono); white-space: pre-wrap; overflow-wrap: anywhere; overflow: auto; resize: none; outline: none; tab-size: 4; }
textarea.b-vtext:focus { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--br-accent-primary) 60%, transparent); }
/* A row that shows only in some states (Settings: hidden while it would do nothing) fades in when it appears. */
.se-appear { animation: se-appear var(--br-motion-panel) var(--br-motion-ease-enter); }
@keyframes se-appear { from { opacity: 0; transform: translateY(-4px); } }
/* Settings › Wi-Fi (FIXES #43): networks as rows; Other networks folds; joining opens the row into a panel. */
.se-wifi-ic { display: inline-flex; color: var(--br-text-secondary); }
.se-fold { cursor: pointer; }
.se-fold:hover, .se-fold:focus-visible { outline: none; box-shadow: var(--br-highlight-edge); }
.se-fold-ic { display: inline-flex; color: var(--br-text-secondary); transition: transform var(--br-motion-move) var(--br-motion-ease-standard); }
.se-fold-ic.open { transform: rotate(180deg); }
.se-join { flex-direction: column; align-items: stretch; gap: 10px; padding-block: 12px; background: var(--br-glass-lift); animation: se-appear var(--br-motion-panel) var(--br-motion-ease-enter); }
.se-join-head { display: flex; align-items: center; gap: var(--br-space-4); }
.se-join-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.se-why, .b-srow .txt .se-why { color: var(--br-state-danger); font-size: 12px; line-height: 16px; }
/* Games: the installed launchers as icon buttons beside the search (FIXES #25). */
.g-launchers { display: inline-flex; align-items: center; gap: 8px; margin-right: 8px; }
.g-launcher { width: 40px; height: 40px; padding: 0; justify-content: center; border-radius: var(--br-shape-pill); }
.g-launcher.b-glass:hover, .g-launcher.b-glass:focus-visible { box-shadow: var(--br-highlight-edge), var(--br-shadow-glass); }
.g-launcher img { width: 24px; height: 24px; object-fit: contain; }
.g-launcher-letter { font: 700 15px/1 var(--br-font-display); }
.g-shelf.dragging { cursor: grabbing; user-select: none; scroll-behavior: auto; }
.g-shelf.dragging .g-cover { pointer-events: none; }
/* Overview's tray (FIXES #45): apps kept running with their windows hidden, marked by a dot under the icon. */
.ov-app.ov-tray, .ov-app.is-running { position: relative; }
/* An open app's dot under its icon in Overview's dock. */
.ov-app.is-running::after { content: ''; position: absolute; bottom: 3px; left: 50%; width: 5px; height: 5px; margin-left: -2.5px; border-radius: 50%; background: var(--br-text-primary); opacity: 0.85; }
.ov-app.ov-tray::after { content: ''; position: absolute; bottom: 3px; left: 50%; width: 5px; height: 5px; margin-left: -2.5px; border-radius: 50%; background: var(--br-accent-primary); }
.ov-head .ov-x + .ov-x { margin-left: -6px; }
/* The D-pad in use hides the pointer over Bridge (FIXES #67); moving the pointer brings it back and clears the highlight. */
:root[data-input=pad], :root[data-input=pad] * { cursor: none !important; }
/* ...and nothing reacts to the hidden pointer (decision 149), so only the D-pad's highlight shows, not also a file the
   pointer happens to rest on. Moving the mouse shows it and gives it back at once (input/focus.ts). */
:root[data-input=pad] body * { pointer-events: none !important; }
/* The browser keeps what it had under the pointer as hovered until the mouse moves, so that leftover hover look is
   taken off while the D-pad is in use (the D-pad's own highlight, and anything selected or open, stay as they are). */
:root[data-input=pad] :is(button, a[href], summary, [role=button], [role=tab], [role=option], [role=switch], [role=radio], [role=menuitem], [data-click],
  .b-ftile, .b-frow, .b-tile, .b-item, .b-srow, .ov-card, .ov-app, .ov-gapp, .ov-bgrow, .se-wall, .se-fold, .osk-key):hover:not(.is-pad-focus, .is-selected, .is-open, [aria-selected="true"], [aria-checked="true"], [aria-current="page"], .primary) {
  background-color: transparent !important; box-shadow: none !important; transform: none !important; }
:root[data-input=pad] .b-btn:not(.quiet):not(.primary):hover:not(.is-pad-focus, .is-open) { background-color: var(--br-glass-tint) !important; box-shadow: inset 0 0 0 1px var(--br-glass-edge), var(--br-shadow-edge-light) !important; }
/* Settings › Controller: the button diagram (FIXES #67). */
.cm svg { width: 100%; max-width: 980px; height: auto; display: block; margin: 0 auto; }
.cm .cm-body { fill: var(--br-glass-lift); stroke: var(--br-glass-edge); stroke-width: 2; }
.cm .cm-trig, .cm .cm-stick { fill: var(--br-glass-lift-strong); stroke: var(--br-glass-edge); stroke-width: 1.5; }
.cm .cm-key { fill: var(--br-tint-10); stroke: var(--br-glass-edge); stroke-width: 1.5; }
.cm .cm-a { fill: var(--br-controller-a); } .cm .cm-b { fill: var(--br-controller-b); } .cm .cm-x { fill: var(--br-controller-x); } .cm .cm-y { fill: var(--br-controller-y); }
.cm .cm-glyph { fill: var(--br-tint-100); font: 700 13px/1 var(--br-font-ui); text-anchor: middle; }
.cm .cm-line { stroke: var(--br-text-secondary); stroke-width: 1; fill: none; opacity: 0.6; }
.cm .cm-dot { fill: var(--br-accent-primary); }
.cm .cm-text { fill: var(--br-text-primary); font: 500 13px/1 var(--br-font-ui); }
.cm .cm-note { margin-top: 10px; font-size: 12px; line-height: 16px; }
/* System flyout: a temperature beside CPU / GPU (FIXES #73). */
.sys-temp { font-weight: 500; color: var(--br-text-secondary); }
/* Settings' section list: pointing at a section brightens it instead of a grey bar; the open one keeps the selected look. */
.se-list .b-item.is-focus:not(.is-selected) { box-shadow: var(--br-highlight-edge); }
.se-list .b-item:not(.is-selected) { color: var(--br-text-secondary); }
.se-list .b-item:not(.is-selected) .b-icon { transition: color var(--br-motion-move) var(--br-motion-ease-standard); }
.se-list .b-item.is-focus:not(.is-selected), .se-list .b-item:hover:not(.is-selected) { color: var(--br-text-primary); }
.se-list .b-item.is-focus:not(.is-selected) .b-icon, .se-list .b-item:hover:not(.is-selected) .b-icon { color: var(--br-accent-primary); }
/* The Terminal tab (FIXES #76). */
.term-page { flex: 1; min-height: 0; display: flex; }   /* laid out like the Server page: the panel fills the page area */
/* One outline: the glass panel itself carries the terminal's dark tint, so its edges and corners are the glass's own. */
.term-panel { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: 4px; padding: 12px; background-color: var(--br-terminal-surface); }
.term-head { display: flex; align-items: center; gap: 10px; padding: 0 8px 0 4px; min-height: 36px; }
.term-head b { font-size: 16px; }
.term-scroll { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; }
.term { position: relative; min-height: 100%; padding: 4px 4px; outline: none; font: 400 13px/18px 'Cascadia Mono', 'Cascadia Code', Consolas, monospace; color: var(--br-terminal-foreground); white-space: pre; cursor: text; user-select: text; }
.term-line { height: 18px; }
.term-cursor { outline: 1px solid var(--br-terminal-foreground); background: var(--br-tint-85) !important; color: var(--br-terminal-background) !important; }
.term:not(:focus) .term-cursor { background: none !important; color: inherit !important; }
.term-measure { position: absolute; visibility: hidden; left: 0; top: 0; }
/* Wallpapers in their order (FIXES #78): dragged to where they should come; numbered while changing in order. */
.se-wall { cursor: grab; }
.se-wall .se-wall-n { position: absolute; left: 8px; bottom: 8px; min-width: 24px; height: 24px; padding: 0 6px; display: grid; place-items: center; border-radius: var(--br-shape-radius-12); background: var(--br-smoke-62); font: 600 12px/1 var(--br-font-ui); }
.se-wall.dragging { z-index: 3; cursor: grabbing; transition: none; box-shadow: var(--br-shadow-lift); opacity: 0.92; }
/* Background apps pinned to keep running (Nov 8): a pin beside them; one not running is dimmed and says so. */
.ov-bgrow .ov-bgpin { display: inline-flex; color: var(--br-accent-primary); }
.ov-bgrow .ov-bgpin .b-icon { width: 14px; height: 14px; }
.ov-bgrow.is-off > img, .ov-bgrow.is-off > .b-icon { opacity: 0.5; }
.ov-bgrow .ov-bgoff { margin-left: auto; font-size: 12px; }
/* Bridge in the dock, always first (FIXES #88). */
.ov-bridge-app .ov-mark { width: 30px; height: 30px; }
.ov-bridge-app .ov-mark svg { width: 30px; height: 21px; }
/* An open app's still picture while a menu is over its card (Windows draws the live one above everything). */
.ov-thumb { position: relative; }
.ov-thumb .ov-snap { position: absolute; inset: 6px; width: calc(100% - 12px); height: calc(100% - 12px); object-fit: contain; border-radius: var(--br-shape-radius-8); }
/* The browser's tab rows: the × of a tab that isn't current shows only while the pointer (or the highlight) is on it. */
.b-item:not(:hover):not(.is-focus) .sb-x { visibility: hidden; }
/* The top bar (decisions 145, 146): what's selected or open (the current tab, the Bridge mark on Home, an icon whose
   panel is open, Settings while it shows) has the selected look, the neon edge with the glow inside, and grows 1.04.
   Where the pointer or the D-pad is has the highlight edge with no glow inside, from the shared rules above. */
.b-topbar .b-btn.is-open, .b-topbar .b-tab.is-open { color: var(--br-text-primary); background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); transform: scale(var(--br-motion-select-scale)); }
/* A highlighted field (decision 152): its border becomes the highlight's core line and the glow sits just outside it.
   Last, so it wins over each kind of field's own edge (on the wallpaper, in glass, on light glass). */
.b-field:hover:not(:has(input:disabled)), .b-field:has(input.is-pad-focus) { border-color: var(--br-highlight-line); box-shadow: var(--br-highlight-glow); }
.b-field.on-wall:hover:not(:has(input:disabled)), .b-field.on-wall:has(input.is-pad-focus) { box-shadow: var(--br-highlight-glow), var(--br-shadow-glass); }

/* ---- Bridge 2.0: packages (PLAN-2.0 item 21; boards in docs/mockups/2.0) ---- */
/* Window: an app's own glass window over the desktop. Kit draws the blur behind it (--br-glass-blur-standalone); this is the
   luminosity layer, the edge and the float shadow, with the Window bar and the page inside. */
.b-window { display: flex; flex-direction: column; gap: var(--br-space-4); padding: var(--br-space-4); border-radius: var(--br-shape-radius); border: 1px solid var(--br-glass-edge);
  background: var(--br-glass-luminosity-dark); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float); }
.b-window.on-bright, .on-bright .b-window { background: var(--br-glass-luminosity-light); }
/* Window bar: the top bar of an app on its own. The app's mark and name, its own tools, a stretch to drag the window
   by, then Settings, a hairline, and Minimize, Maximize (Restore when maximised) and Close: all 32px quiet icon buttons. */
.b-topbar.b-winbar { grid-template-columns: auto 1fr auto; }
.b-winbar .b-logo { font: 500 14px/20px var(--br-font-display); letter-spacing: 0; text-transform: none; }
.b-winbar .drag { align-self: stretch; }
.b-winbar .sep { width: 1px; height: 20px; flex: none; background: var(--br-glass-edge); margin: 0 var(--br-space-1); }
/* Package icon: a package's mark in an inset tile. 40px in a row, 48px (.md) on a Store card, 52px (.lg) in a dialog,
   72px (.xl) on the Store's featured card. */
.b-pkg-icon { width: var(--br-size-control); height: var(--br-size-control); flex: none; display: grid; place-items: center; border-radius: var(--br-shape-radius);
  background: var(--br-glass-inset); border: 1px solid var(--br-glass-edge); box-shadow: var(--br-shadow-edge-light); color: var(--br-text-primary); }
.b-pkg-icon.md { width: 48px; height: 48px; }
.b-pkg-icon.lg { width: var(--br-size-control-lg); height: var(--br-size-control-lg); }
.b-pkg-icon.lg .b-icon { width: 26px; height: 26px; }
.b-pkg-icon.xl { width: 72px; height: 72px; }
.b-pkg-icon.xl .b-icon { width: 32px; height: 32px; }
/* Permission list: what a package can do, in plain words: a label ("It can") and one 36px row per power, each with
   its icon. In the Add to Bridge dialog and under a package's row in Settings > Apps. */
.b-perms { padding: var(--br-space-2); display: flex; flex-direction: column; gap: 2px; border-radius: var(--br-shape-radius); background: var(--br-glass-inset); border: 1px solid var(--br-glass-edge); }
.b-perms > .b-label { padding: var(--br-space-1) var(--br-space-2); }
.b-perms > .b-item { height: 36px; padding: 0 var(--br-space-2); cursor: default; }
/* Package row: a settings row for one installed package: its icon, name, a line of facts (version, publisher, what's
   waiting), then Update or Update Bridge, the Show in Bridge switch and More. Its permission list sits under it,
   lined up with the name. */
.b-srow.b-pkg > .b-pkg-icon + .txt b { font-weight: 600; }
.b-srow.b-pkg + .b-perms { margin: 0 var(--br-space-4) 6px 72px; }
/* Store card: one package in the Store: icon, name and publisher, two lines of what it is, then one full-width
   button (Install, Installed, Update) or its download progress in the button's place. */
.b-store-card { padding: var(--br-space-4); display: flex; flex-direction: column; gap: var(--br-space-3); border-radius: var(--br-shape-radius); background: var(--br-glass-inset);
  border: 1px solid var(--br-glass-edge); box-shadow: var(--br-shadow-edge-light); }
.b-store-card .head { display: flex; align-items: center; gap: var(--br-space-3); min-width: 0; }
.b-store-card .head .txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.b-store-card .head .txt b { font-weight: 600; }
.b-store-card .desc { min-height: var(--br-size-control); color: var(--br-text-secondary); }
.b-store-card .progress { height: var(--br-size-control); display: flex; align-items: center; gap: var(--br-space-3); }
.b-store-card .progress .b-track { flex: 1; height: 4px; }
.b-store-card.featured { flex-direction: row; align-items: center; gap: var(--br-space-5); padding: var(--br-space-5); }
.b-store-card.featured .txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.b-store-card.featured > .b-btn { min-width: 120px; }

/* ---- Phone: a package's mobile UI in Bridge Mobile (PLAN-2.0 item 36a; the Mobile boards in docs/mockups/2.0) ---- */
/* The same components at phone sizes: one column, 16px from the screen's edges (and clear of the notch and the home
   bar), everything a finger presses at least 44px, and nothing that lights up under a pointer that isn't there. */
.b-phone { min-height: 100dvh; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--br-space-3); font-family: var(--br-font-ui); color: var(--br-text-primary);
  padding: max(var(--br-space-4), env(safe-area-inset-top)) max(var(--br-space-4), env(safe-area-inset-right)) max(var(--br-space-4), env(safe-area-inset-bottom)) max(var(--br-space-4), env(safe-area-inset-left));
  -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
.b-phone .b-btn, .b-phone .b-field, .b-phone .b-seg > * { min-height: var(--br-size-touch); }
.b-phone .b-btn.sm { min-height: var(--br-size-touch); }
.b-phone .b-icon-btn { width: var(--br-size-touch); height: var(--br-size-touch); }
.b-phone .b-item { min-height: var(--br-size-touch); height: auto; }
.b-phone .b-field input { font-size: 16px; }   /* smaller text makes a phone zoom the page when the field is tapped */
/* The bar at the top: Back (to the app drawer), the app's name over the PC it is talking to, and one action. */
.b-phonebar { flex: none; height: var(--br-size-phone-bar); padding: 0 var(--br-space-2); display: flex; align-items: center; gap: var(--br-space-2); }
.b-phonebar .name { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.b-phonebar .name:first-child { padding-left: var(--br-space-2); }
.b-phonebar .name b { font: 600 17px/22px var(--br-font-display); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.b-phonebar .pc { display: flex; align-items: center; gap: 6px; font-size: 12px; line-height: 16px; color: var(--br-text-secondary); }
.b-phonebar .pc::before { content: ""; width: 7px; height: 7px; border-radius: var(--br-shape-pill); background: var(--br-state-success); }
.b-phonebar .pc.away::before { background: var(--br-text-tertiary); }
/* No hover on a phone: a finger leaves the last thing it touched "hovered", so the highlight edge is switched off
   there. What is selected, open or pressed keeps its own look. */
@media (hover: none) {
  .b-phone { --br-highlight-edge: 0 0 0 0 transparent; --br-highlight-glow: 0 0 0 0 transparent; --br-highlight-line: var(--br-glass-edge); }
}

/* ---- Money (Bridge Money: mockups 2.0/money). Money on a calendar and in categories. ------------------------------ */
/* Six category colours, in order: the accent, then pink, amber, coral, blue and grey (none is green: money in is green). A seventh category and on share grey. */
.b-money-fig { font: 600 40px/44px var(--br-font-mono); font-variant-numeric: tabular-nums; letter-spacing: -0.5px; white-space: nowrap; }
.b-money-fig.sm { font-size: 24px; line-height: 28px; }
.b-money-dot { width: 10px; height: 10px; border-radius: var(--br-shape-radius-3); flex: none; background: var(--cat, var(--br-money-cat-6)); }
.b-money-stack { display: flex; gap: 3px; height: 12px; }
.b-money-stack > i { min-width: 4px; border-radius: var(--br-shape-pill); background: var(--cat, var(--br-money-cat-6)); transition: flex-grow var(--br-motion-panel) var(--br-motion-ease-standard); }
.b-money .b-track > i { background: var(--cat, var(--br-accent-primary)); transition: width var(--br-motion-panel) var(--br-motion-ease-standard); }
.b-money-donut { width: 180px; height: 180px; flex: none; border-radius: var(--br-shape-pill); display: grid; place-items: center; background: var(--donut, var(--br-glass-inset)); }
.b-money-donut > div { width: 122px; height: 122px; border-radius: var(--br-shape-pill); background: var(--br-wallpaper-base); display: flex; flex-direction: column; align-items: center; justify-content: center; }
/* The calendar: seven equal columns. A day is brighter the more was spent on it (--heat, 0% to 40% of the accent). */
.b-money-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
.b-money-cal > .b-label { padding: 0 var(--br-space-2); }
.b-money-day { min-height: 96px; min-width: 0; padding: var(--br-space-2); border-radius: var(--br-shape-radius); display: flex; flex-direction: column; gap: 3px; cursor: pointer;
  background: color-mix(in srgb, var(--br-accent-primary) var(--heat, 0%), var(--br-glass-inset)); transition: box-shadow var(--br-motion-move) var(--br-motion-ease-standard), background var(--br-motion-move) var(--br-motion-ease-standard); }
.b-money-day:hover, .b-money-day:focus-visible { box-shadow: var(--br-highlight-edge); outline: none; }
.b-money-day.is-today { box-shadow: var(--br-selected-edge); }
.b-money-day.is-out { opacity: 0.45; }
.b-money-day > .pills { margin-top: auto; display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.b-money-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: var(--br-space-2); }
.b-money-week > .b-money-day { min-height: 150px; padding: var(--br-space-3); }
/* A small pill on a day or a row: a bill (amber), payday (the accent), paid or saving (green). */
.b-money-pill { height: 20px; padding: 0 8px; border-radius: var(--br-shape-pill); display: inline-block; max-width: 100%; box-sizing: border-box; font: 600 11px/20px var(--br-font-ui); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  background: color-mix(in srgb, var(--tone, var(--br-text-secondary)) 22%, transparent); color: color-mix(in srgb, var(--tone, var(--br-text-secondary)) 55%, var(--br-text-primary)); }
.b-money-pill.bill { --tone: var(--br-state-warning); }
.b-money-pill.payday { --tone: var(--br-accent-primary); }
.b-money-pill.paid, .b-money-pill.saving { --tone: var(--br-state-success); }
.b-money-icon { width: 36px; height: 36px; flex: none; border-radius: var(--br-shape-pill); background: var(--br-glass-lift); display: grid; place-items: center; }
.b-money-keys { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--br-space-2); }
.b-money-keys > .b-btn { min-width: 0; height: var(--br-size-control-lg); padding: 0; font: 600 18px/1 var(--br-font-mono); }
/* On a phone: days are small squares with a dot for a bill or payday, and the four pages are a bar at the bottom. */
.b-phone .b-money-cal { gap: var(--br-space-1); }
.b-phone .b-money-day { min-height: var(--br-size-touch); padding: var(--br-space-1); align-items: center; gap: 0; }
.b-phone .b-money-day > .pills { flex-direction: row; justify-content: center; }
.b-money-pill.dot, .b-phone .b-money-day .b-money-pill { width: 6px; height: 6px; padding: 0; font-size: 0; background: var(--tone, var(--br-text-secondary)); }
.b-phone .b-money-fig { font-size: 32px; line-height: 36px; }
.b-money-tabs { position: sticky; bottom: var(--br-space-3); margin-top: auto; display: flex; gap: var(--br-space-2); align-items: center; }
.b-money-tabs > nav { flex: 1; min-width: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); padding: var(--br-space-1); }
.b-money-tabs > nav > button { all: unset; box-sizing: border-box; min-height: var(--br-size-control-lg); border-radius: var(--br-shape-radius); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  font: 500 11px/14px var(--br-font-ui); color: var(--br-text-secondary); cursor: pointer; transition: background var(--br-motion-move) var(--br-motion-ease-standard), color var(--br-motion-move) var(--br-motion-ease-standard); }
.b-money-tabs > nav > button.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); color: var(--br-text-primary); }
.b-money-tabs > .b-icon-btn { width: var(--br-size-control-lg); height: var(--br-size-control-lg); border-radius: var(--br-shape-pill); }

/* ---- Layout presets (Bridge Themes: Layout). A theme, or the person, rearranges Bridge within a fixed set of options;
   each is a preset here, keyed by a name Kit puts on the root (kit/web/theme/layout.ts), so every app follows it and
   none builds its own. Density, the frame gap and the corners are token values (size.control, space, shape.radius).
   Only Bridge's own bar moves (.b-shell > .b-topbar): a window's bar is its top edge, always. */
.b-shell { flex-direction: column; }
.b-tabs > .b-tab { grid-column: var(--c, auto); }
.tb-clock { padding: 0 8px; white-space: nowrap; text-align: center; min-width: calc(var(--clock-ch, 8) * 1ch); box-sizing: content-box; }
.tb-apps { margin-left: var(--br-space-2); }
.tb-tools { display: flex; align-items: center; gap: var(--br-space-1); }

/* Bar position: top (Bridge's own), bottom, or left (the bar stands up: brand on top, the tabs run downwards, the
   status items at the bottom). With icons for tabs a bar on the left is a rail, one icon wide. */
:root[data-br-bar="bottom"] .b-shell > .b-topbar { order: 9; }
:root[data-br-bar="left"] .b-shell { flex-direction: row; }
:root[data-br-bar="left"] .b-shell > .b-topbar { --bar-w: 208px; width: var(--bar-w); height: auto; box-sizing: border-box; display: flex; flex-direction: column; justify-content: space-between; align-items: stretch; row-gap: var(--br-space-4); padding: var(--br-space-2); }
:root[data-br-bar="left"][data-br-tabs="icons"] .b-shell > .b-topbar { --bar-w: 72px; }
:root[data-br-bar="left"] .b-shell > .b-topbar > .left, :root[data-br-bar="left"] .b-shell > .b-topbar > .right { flex: none; flex-wrap: wrap; justify-content: flex-start; row-gap: var(--br-space-1); }
:root[data-br-bar="left"] .b-shell > .b-topbar .b-tabs { flex: none; grid-auto-flow: row; grid-auto-columns: auto; grid-template-columns: minmax(0, 1fr); }
:root[data-br-bar="left"] .b-shell > .b-topbar .b-tabs > .b-tab { grid-column: 1; grid-row: var(--c, auto); justify-content: flex-start; }
:root[data-br-bar="left"] .b-shell > .b-topbar .b-tabs > .b-slide { grid-column: 1; grid-row: var(--c); }
:root[data-br-bar="left"] .b-shell > .b-topbar .tb-apps { margin-left: 0; }
:root[data-br-bar="left"] .b-shell > .b-topbar .tb-tools { flex-wrap: wrap; justify-content: inherit; row-gap: var(--br-space-1); max-width: 100%; }
:root[data-br-bar="left"] .b-shell > .b-topbar .tb-clock { flex: 1 0 100%; box-sizing: border-box; min-width: 0; }
:root[data-br-bar="left"][data-br-tabs="icons"] .b-shell > .b-topbar > .left, :root[data-br-bar="left"][data-br-tabs="icons"] .b-shell > .b-topbar > .right { justify-content: center; }
:root[data-br-bar="left"][data-br-tabs="icons"] .b-shell > .b-topbar .b-tabs > .b-tab { justify-content: center; padding: 0; }
:root[data-br-bar="left"][data-br-tabs="icons"] .b-shell > .b-topbar .b-logo { padding: 0; width: 100%; justify-content: center; }
:root[data-br-bar="left"][data-br-tabs="icons"] .b-shell > .b-topbar .b-logo > span { display: none; }
:root[data-br-bar="left"][data-br-tabs="icons"] .b-shell > .b-topbar .tb-clock { white-space: normal; padding: 0; }

/* Bar style: a floating pill (Bridge's own), full width (edge to edge, against the screen's edge), or islands (the
   three groups are each their own glass). */
:root[data-br-bar-style="full"] .b-shell > .b-topbar { margin: calc(-1 * var(--br-space-4)) calc(-1 * var(--br-space-4)) 0; border-radius: 0; border-width: 0 0 1px; }
:root[data-br-bar-style="full"][data-br-bar="bottom"] .b-shell > .b-topbar { margin: 0 calc(-1 * var(--br-space-4)) calc(-1 * var(--br-space-4)); border-width: 1px 0 0; }
:root[data-br-bar-style="full"][data-br-bar="left"] .b-shell > .b-topbar { margin: calc(-1 * var(--br-space-4)) 0 calc(-1 * var(--br-space-4)) calc(-1 * var(--br-space-4)); border-width: 0 1px 0 0; }
.b-topbar.islands { padding: 0; }
.b-topbar.islands > .b-island { position: relative; height: 100%; box-sizing: border-box; display: flex; align-items: center; padding: 0 var(--br-space-2); }
.b-topbar.islands > .left { justify-self: start; }
.b-topbar.islands > .right { justify-self: end; }
:root[data-br-bar="left"] .b-shell > .b-topbar.islands { padding: 0; }
:root[data-br-bar="left"] .b-shell > .b-topbar.islands > .b-island { height: auto; padding: var(--br-space-2); }
:root[data-br-bar="left"] .b-shell > .b-topbar.islands > .mid { flex-direction: column; align-items: stretch; }

/* Bar contents: the order of the three groups (brand, tabs, status), and the optional items a layout leaves out. The
   tabs' column is as wide as the tabs; the other two share what is left. */
:root[data-br-order^="tabs-"] .b-shell > .b-topbar { grid-template-columns: auto 1fr 1fr; }
:root[data-br-order$="-tabs"] .b-shell > .b-topbar { grid-template-columns: 1fr 1fr auto; }
:root[data-br-order="brand-status-tabs"] .b-shell > .b-topbar > .right { order: 2; }
:root[data-br-order="brand-status-tabs"] .b-shell > .b-topbar > :is(.b-tabs, .mid) { order: 3; }
:root[data-br-order="tabs-brand-status"] .b-shell > .b-topbar > .left { order: 2; }
:root[data-br-order="tabs-brand-status"] .b-shell > .b-topbar > .right { order: 3; }
:root[data-br-order="tabs-status-brand"] .b-shell > .b-topbar > .right { order: 2; justify-content: flex-start; }
:root[data-br-order="tabs-status-brand"] .b-shell > .b-topbar > .left { order: 3; justify-content: flex-end; }
:root[data-br-order="status-tabs-brand"] .b-shell > .b-topbar > .right { order: 1; justify-content: flex-start; }
:root[data-br-order="status-tabs-brand"] .b-shell > .b-topbar > :is(.b-tabs, .mid) { order: 2; }
:root[data-br-order="status-tabs-brand"] .b-shell > .b-topbar > .left { order: 3; justify-content: flex-end; }
:root[data-br-order="status-brand-tabs"] .b-shell > .b-topbar > .right { order: 1; justify-content: flex-start; }
:root[data-br-order="status-brand-tabs"] .b-shell > .b-topbar > .left { order: 2; }
:root[data-br-order="status-brand-tabs"] .b-shell > .b-topbar > :is(.b-tabs, .mid) { order: 3; }
:root[data-br-order="status-tabs-brand"] .b-shell > .b-topbar.islands > .right, :root[data-br-order="tabs-status-brand"] .b-shell > .b-topbar.islands > .right, :root[data-br-order="status-brand-tabs"] .b-shell > .b-topbar.islands > .right { justify-self: start; }
:root[data-br-order="status-tabs-brand"] .b-shell > .b-topbar.islands > .left, :root[data-br-order="tabs-status-brand"] .b-shell > .b-topbar.islands > .left { justify-self: end; }
:root[data-br-hide~="wordmark"] .b-shell > .b-topbar .b-logo > span { display: none; }

/* Tab style: names (Bridge's own), icons, or icons and names. A tab with no icon keeps its name. */
:root[data-br-tabs="icons+text"] .b-tab { gap: var(--br-space-2); }
:root[data-br-tabs="icons"] .b-tab .b-icon { width: 18px; height: 18px; }

/* Buttons: rounded (Bridge's own), pill or square; a button that has an icon can show its words, its icon, or both.
   Its words stay its name for a screen reader when only the icon shows. */
:root[data-br-buttons="pill"] .b-btn { border-radius: var(--br-shape-pill); }
:root[data-br-buttons="square"] .b-btn { border-radius: var(--br-shape-radius-2); }
:root[data-br-button-label="icon"] .b-btn:not(.b-icon-btn):has(> .b-icon) { min-width: 0; padding: 0; aspect-ratio: 1; justify-content: center; }
:root[data-br-button-label="icon"] .b-btn:not(.b-icon-btn):has(> .b-icon) > .lbl { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
:root[data-br-button-label="text"] .b-btn:not(.b-icon-btn):has(> .lbl) > .b-icon { display: none; }

/* Side panels (the browser's sidebar, Files' details): on the left or on the right. */
:root[data-br-panels="left"] .b-autopanel { right: auto; left: 0; }
:root[data-br-panels="left"] .b-edge-pill.right { right: auto; left: 5px; }
:root[data-br-panels="left"] .b-edge-gutter.right { right: auto; left: 0; }
:root[data-br-panels="left"] aside.b-panel { order: -1; }
:root[data-br-panels="left"] nav.b-side { order: -2; }
:root[data-br-panels="right"] aside.b-panel { order: 9; }

/* ---- Bridge Themes (docs/themes/DESIGN.md, App design; mockups Standalone-Library, Standalone-Store, Home-Editor).
   Its three pages (Library, Store, Editor), first-time setup, and the Editor's live preview. */
.th-app { height: 100vh; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--br-space-4); }
.th-page { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--br-space-4); }
.th-row { display: flex; align-items: center; gap: var(--br-space-3); flex: none; }
.th-bar-end { display: flex; align-items: center; min-width: 0; }
.th-editbar.in-bar { gap: var(--br-space-2); }
.th-editbar.in-bar .b-field { height: var(--br-size-control-sm); width: 180px; }
.th-editbar.in-bar > span[style] { display: none; }
.th-tabs { margin-left: var(--br-space-3); }
.th-empty { padding: var(--br-space-6) var(--br-space-4); display: flex; flex-direction: column; align-items: flex-start; gap: var(--br-space-2); }
.th-actions { display: flex; align-items: center; gap: var(--br-space-3); flex-wrap: wrap; }
.th-actions > .b-btn:not(.b-icon-btn) { min-width: 132px; }
.th-note { padding: var(--br-space-2) 0 0; font-size: 12px; line-height: 16px; }

/* A theme in miniature: its ground with its two accents glowing through, a small bar, a button, a few tiles. */
.th-mini { position: relative; flex: none; height: 92px; overflow: hidden; border-radius: var(--br-shape-radius-10);
  background: radial-gradient(120% 140% at 20% 0%, color-mix(in srgb, var(--m-accent) 45%, transparent), transparent 60%), radial-gradient(120% 140% at 90% 30%, color-mix(in srgb, var(--m-accent2) 50%, transparent), transparent 62%), var(--m-ground); }
.th-mini > i, .th-mini .tiles > i { position: absolute; display: block; }
/* Its real picture (the package's preview.png), over the drawing once it has loaded. */
.th-mini > .th-pic { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity var(--br-motion-move) var(--br-motion-ease-standard); }
.th-mini > .th-pic.shown { opacity: 1; }
.th-mini .bar { left: 8px; right: 8px; top: 8px; height: 16px; border-radius: var(--m-r); border: 1px solid color-mix(in srgb, var(--m-ink) 28%, transparent); }
.th-mini .bar > b { position: absolute; left: 14%; top: 3px; bottom: 3px; width: 12%; border-radius: var(--m-r); background: var(--m-accent); }
.th-mini .bar > s { position: absolute; top: 6px; height: 3px; width: 9%; border-radius: var(--br-shape-pill); background: color-mix(in srgb, var(--m-ink) 55%, transparent); }
.th-mini .bar > s:nth-of-type(1) { left: 30%; } .th-mini .bar > s:nth-of-type(2) { left: 42%; }
.th-mini .go { left: 10px; bottom: 10px; width: 44px; height: 14px; border-radius: var(--m-r); background: linear-gradient(90deg, var(--m-accent), var(--m-accent2)); }
.th-mini.large { height: auto; width: 448px; aspect-ratio: 16 / 9; border-radius: var(--br-shape-radius); }
.th-mini.large .bar { left: 12px; right: 12px; top: 12px; height: 30px; }
.th-mini.large .bar > b { top: 5px; bottom: 5px; } .th-mini.large .bar > s { top: 13px; }
.th-mini.large .line { left: 12px; top: 40%; width: 31%; height: 10px; border-radius: var(--br-shape-pill); background: color-mix(in srgb, var(--m-ink) 90%, transparent); }
.th-mini.large .go { left: 12px; bottom: auto; top: 50%; width: 76px; height: 28px; }
.th-mini.large .btn { left: 96px; top: 50%; width: 76px; height: 28px; border-radius: var(--m-r); border: 1px solid color-mix(in srgb, var(--m-ink) 25%, transparent); }
.th-mini.large .tiles > i { bottom: 12px; width: 56px; height: 74px; border-radius: var(--m-r); background: color-mix(in srgb, var(--m-ink) 12%, transparent); }
.th-mini.large .tiles > i:nth-child(1) { left: 12px; } .th-mini.large .tiles > i:nth-child(2) { left: 76px; } .th-mini.large .tiles > i:nth-child(3) { left: 140px; } .th-mini.large .tiles > i:nth-child(4) { left: 204px; }

/* Library: the hero, then the cards. */
.th-hero { flex: none; display: flex; flex-direction: row; gap: var(--br-space-6); padding: var(--br-space-5); align-items: stretch; }
.th-hero-text { display: flex; flex-direction: column; gap: var(--br-space-2); min-width: 0; flex: 1; }
.th-hero-text h1, .th-setup-body h1 { margin: 0; font: 600 30px/36px var(--br-font-display); }
.th-hero-text .th-actions { margin-top: auto; }
.th-swatches { display: flex; align-items: center; gap: var(--br-space-2); margin-top: var(--br-space-2); }
.th-swatches > i, .th-dots > i { width: 20px; height: 20px; border-radius: var(--br-shape-pill); flex: none; box-shadow: inset 0 0 0 1px var(--br-tint-28); }
.th-swatches > span { margin-left: var(--br-space-1); }
.th-grid-wrap { flex: 1; min-height: 0; overflow-y: auto; margin: calc(-1 * var(--br-space-2)); padding: var(--br-space-2); }
.th-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(220px * var(--tile-scale, 1)), 1fr)); gap: var(--br-space-4); align-content: start; }
.th-card { position: relative; display: grid; grid-template-columns: 1fr auto; gap: var(--br-space-2) var(--br-space-2); padding: var(--br-space-2); text-align: left; color: var(--br-text-primary); font: inherit; cursor: pointer;
  border-radius: var(--br-shape-radius); transition: transform var(--br-motion-move) var(--br-motion-ease-standard), box-shadow var(--br-motion-move) var(--br-motion-ease-standard); }
.th-card > .th-mini { grid-column: 1 / -1; }
.th-card:hover, .th-card:focus-visible { box-shadow: var(--br-highlight-edge); outline: none; }
.th-card.is-selected { background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); transform: scale(var(--br-motion-select-scale)); }
.th-card-text { display: flex; flex-direction: column; min-width: 0; padding: 0 var(--br-space-1) var(--br-space-1); }
.th-card-text > * { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.th-card-text > .b-muted { font-size: 12px; line-height: 16px; }
.th-dots { display: flex; gap: var(--br-space-1); align-items: center; padding-right: var(--br-space-1); }
.th-dots > i { width: 12px; height: 12px; }
.th-tag { position: absolute; right: 16px; top: 68px; padding: 0 var(--br-space-2); border-radius: var(--br-shape-pill); background: var(--br-glass-strong); box-shadow: inset 0 0 0 1px var(--br-tint-28); font: 600 11px/20px var(--br-font-ui); }

/* Store: the grid, and a theme's sheet beside it. */
.th-store { flex: 1; min-height: 0; display: flex; gap: var(--br-space-4); }
.th-sheet { width: 480px; flex: none; display: flex; flex-direction: column; gap: var(--br-space-3); padding: var(--br-space-5); overflow-y: auto; }
.th-sheet .th-mini.large { width: 100%; }
.th-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: var(--br-space-3); }
.th-sheet-head h2, .th-controls h2 { margin: 0; font: 600 20px/28px var(--br-font-display); }
.th-brings { margin: 0; padding-left: var(--br-space-5); display: flex; flex-direction: column; gap: var(--br-space-1); color: var(--br-text-secondary); }
.th-trying { flex: none; display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: var(--br-space-4); padding: var(--br-space-2) var(--br-space-2) var(--br-space-2) var(--br-space-4); }

/* Editor: the categories, the controls, the preview. */
.th-editbar .b-field { height: var(--br-size-control); }
.th-group-btns { display: flex; gap: var(--br-space-1); }
.th-live { display: flex; align-items: center; gap: var(--br-space-2); padding: 0 var(--br-space-2); }
.th-badge.ok .b-icon { color: var(--br-state-success); } .th-badge.warn .b-icon { color: var(--br-state-warning); } .th-badge.blocked .b-icon { color: var(--br-state-danger); }
.th-problems { flex: none; display: flex; flex-direction: column; gap: var(--br-space-2); padding: var(--br-space-4); max-height: 240px; overflow-y: auto; }
.th-problem { display: flex; align-items: center; gap: var(--br-space-3); min-height: var(--br-size-control-sm); }
.th-problem .lvl { flex: none; width: 168px; font-weight: 600; } .th-problem .lvl.blocked { color: var(--br-state-danger); } .th-problem .lvl.warning { color: var(--br-state-warning); }
.th-problem .what { flex: 1; min-width: 0; }
.th-cols { flex: 1; min-height: 0; display: flex; gap: var(--br-space-4); }
.th-rail { flex: none; width: 92px; padding: var(--br-space-2); overflow-y: auto; }
.th-cats { display: flex; flex-direction: column; gap: var(--br-space-1); }
.th-cat { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-height: 48px; padding: var(--br-space-1) 0; border: 0; background: none; cursor: pointer; border-radius: var(--br-shape-radius-12); color: var(--br-text-secondary); font: 500 11px/14px var(--br-font-ui); }
.th-cat:hover, .th-cat:focus-visible { color: var(--br-text-primary); box-shadow: var(--br-highlight-edge); outline: none; }
.th-cat.is-selected { color: var(--br-text-primary); background: var(--br-selected-fill); box-shadow: var(--br-selected-edge); }
.th-choose { padding: var(--br-space-6); gap: var(--br-space-3); overflow-y: auto; }
.th-choose h1 { margin: 0; font: 600 30px/36px var(--br-font-display); }
.th-controls { flex: none; width: 380px; display: flex; flex-direction: column; gap: var(--br-space-3); padding: var(--br-space-4); min-height: 0; }
.th-controls-list { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--br-space-2); margin-right: calc(-1 * var(--br-space-2)); padding-right: var(--br-space-2); }
.th-about { margin-top: calc(-1 * var(--br-space-1)); }
.th-group { display: flex; flex-direction: column; gap: var(--br-space-2); padding-top: var(--br-space-3); }
.th-ctl { display: flex; flex-direction: column; gap: var(--br-space-2); padding: var(--br-space-3); border-radius: var(--br-shape-radius-12); background: var(--br-glass-inset); box-shadow: inset 0 0 0 1px var(--br-tint-10); }
.th-ctl.inline { flex-direction: row; align-items: center; justify-content: space-between; gap: var(--br-space-4); min-height: var(--br-size-control); padding-top: var(--br-space-1); padding-bottom: var(--br-space-1); }
.th-ctl-head { display: flex; align-items: center; gap: var(--br-space-2); min-height: 20px; }
.th-ctl .nm { font-weight: 600; flex: 1; min-width: 0; }
.th-ctl .val { color: var(--br-text-secondary); font-size: 13px; }
.th-reset { flex: none; width: 20px; height: 20px; padding: 0; border: 0; border-radius: var(--br-shape-pill); background: none; cursor: pointer; position: relative; }
.th-reset::after { content: ""; position: absolute; inset: 6px; border-radius: var(--br-shape-pill); background: var(--br-accent-primary); }
.th-reset:hover, .th-reset:focus-visible { box-shadow: var(--br-highlight-edge); outline: none; }
.th-choices { display: flex; flex-wrap: wrap; gap: var(--br-space-2); }
.th-colour { display: flex; align-items: center; gap: var(--br-space-2); }
.th-swatch { flex: none; width: var(--br-size-control); height: var(--br-size-control); padding: 0; border: 0; cursor: pointer; border-radius: var(--br-shape-radius-10); box-shadow: inset 0 0 0 1px var(--br-tint-34), var(--br-shadow-edge-light); }
.th-swatch.sm { width: var(--br-size-control-sm); height: var(--br-size-control-sm); }
.th-swatch:hover, .th-swatch:focus-visible { box-shadow: inset 0 0 0 1px var(--br-tint-34), var(--br-highlight-edge); outline: none; }
.th-picker { display: flex; flex-direction: column; gap: var(--br-space-3); padding-top: var(--br-space-2); }
.th-picker > label { display: grid; grid-template-columns: 84px 1fr; align-items: center; gap: var(--br-space-3); color: var(--br-text-secondary); font-size: 13px; }
.th-picks { display: flex; flex-wrap: wrap; gap: var(--br-space-2); }
.th-bad { color: var(--br-state-danger); font-size: 12px; line-height: 16px; }
.th-preview { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--br-space-3); padding: var(--br-space-4); }
.th-fit { flex: 1; min-height: 0; display: grid; place-items: center; overflow: hidden; }
.th-fit > div { overflow: hidden; border-radius: var(--br-shape-radius-12); box-shadow: inset 0 0 0 1px var(--br-tint-14), var(--br-shadow-glass); }
.th-frame { width: 1440px; height: 900px; border: 0; display: block; }
.th-editor.preview-only .th-rail, .th-editor.preview-only .th-controls { display: none; }

/* First-time setup. */
.th-setup { align-items: center; justify-content: center; }
.th-setup-card { width: min(920px, 100%); height: min(620px, 100%); display: flex; flex-direction: column; gap: var(--br-space-4); padding: var(--br-space-6); box-sizing: border-box; }
.th-setup-steps { display: flex; gap: var(--br-space-2); }
.th-setup-steps > i { width: 28px; height: 4px; border-radius: var(--br-shape-pill); background: var(--br-tint-18); }
.th-setup-steps > i.done { background: var(--br-tint-55); } .th-setup-steps > i.on { background: var(--br-accent-primary); }
.th-setup-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: var(--br-space-3); }
.th-setup-body.centre { align-items: center; justify-content: center; text-align: center; padding: 0 var(--br-space-6); }
.th-setup-mark { color: var(--br-accent-primary); display: inline-flex; margin-bottom: var(--br-space-4); }
.th-setup-mark > svg { width: 72px; height: 72px; }
.th-setup-list { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--br-space-2); }
.th-setup-row { display: flex; align-items: center; justify-content: space-between; gap: var(--br-space-4); min-height: var(--br-size-control-lg); padding: 0 var(--br-space-4); border-radius: var(--br-shape-radius-12); background: var(--br-glass-inset); }
.th-setup-row > span:first-child { display: flex; flex-direction: column; }
.th-setup-foot { display: flex; align-items: center; gap: var(--br-space-3); }
.th-setup-foot .b-btn { min-width: 112px; }

/* The Editor's preview page (preview.tsx): a Bridge page of made-up things, on a wallpaper of the theme's own colours. */
.th-previewing, .th-previewing body { margin: 0; height: 100%; overflow: hidden; background: var(--br-wallpaper-base); color: var(--br-text-primary); font-family: var(--br-font-ui); }
.th-shell { position: relative; height: 100vh; box-sizing: border-box; display: flex; gap: var(--br-space-4); padding: var(--br-space-4); overflow: hidden; }
.th-wall { position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(70% 90% at 18% 12%, rgba(var(--br-accent-primary-rgb), 0.34), transparent 62%), radial-gradient(60% 80% at 88% 78%, color-mix(in srgb, var(--br-accent-secondary) 34%, transparent), transparent 64%), var(--br-wallpaper-base); }
.th-shell > :not(.th-wall):not(.th-point) { position: relative; z-index: 1; }
.th-scene { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; gap: var(--br-space-4); }
.th-scene-grow { flex: 1; }
.th-home { padding: var(--br-space-4) var(--br-space-5) var(--br-space-6); align-items: flex-start; }
.th-home > .b-field { align-self: center; }
.th-scene h1.title { margin: 0; font: 700 48px/52px var(--br-font-display); }
.th-covers { display: flex; gap: var(--br-space-5); margin-top: var(--br-space-4); }
.th-covers.small { margin-top: 0; gap: var(--br-space-3); }
.th-cover { width: calc(150px * var(--tile-scale, 1)); height: calc(200px * var(--tile-scale, 1)); flex: none; display: flex; align-items: flex-end; padding: var(--br-space-3); box-sizing: border-box; font-weight: 600;
  background: linear-gradient(160deg, color-mix(in srgb, var(--br-accent-primary) calc(46% - var(--k, 0) * 8%), var(--br-skin-ground)), color-mix(in srgb, var(--br-accent-secondary) calc(24% + var(--k, 0) * 6%), var(--br-skin-ground))); }
.th-covers.small .th-cover { width: 92px; height: 120px; font-size: 12px; }
.th-store-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--br-space-4); }
.th-appcard { display: flex; flex-direction: row; align-items: center; gap: var(--br-space-3); padding: var(--br-space-4); }
.th-appcard .ic { flex: none; width: 48px; height: 48px; display: grid; place-items: center; border-radius: var(--br-shape-radius-12); background: var(--br-glass-lift); }
.th-appcard .tx { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.th-split { flex-direction: row; }
.th-places { padding: var(--br-space-3); display: flex; flex-direction: column; gap: var(--br-space-1); }
.th-list { flex: 1; min-width: 0; padding: var(--br-space-3); display: flex; flex-direction: column; gap: var(--br-space-1); }
.th-details { width: 320px; flex: none; padding: var(--br-space-4); display: flex; flex-direction: column; gap: var(--br-space-3); }
.th-code { flex: 1; margin: 0; padding: var(--br-space-4); border-radius: var(--br-shape-radius-12); background: var(--br-terminal-background); color: var(--br-terminal-foreground); font: 400 14px/22px var(--br-font-mono); white-space: pre-wrap; }
.th-canvas { align-items: center; justify-content: center; }
.th-art { position: relative; width: 420px; height: 300px; }
.th-art > i { position: absolute; border-radius: var(--br-shape-radius); }
.th-art > i:nth-child(1) { inset: 0 120px 80px 0; background: var(--br-accent-primary); opacity: 0.85; }
.th-art > i:nth-child(2) { inset: 70px 30px 20px 150px; background: var(--br-accent-secondary); opacity: 0.8; }
.th-art > i:nth-child(3) { inset: 150px 200px 0 60px; border-radius: var(--br-shape-pill); background: var(--br-tint-70); }
.th-sheet-parts { flex: 1; min-height: 0; overflow-y: auto; padding: var(--br-space-5); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--br-space-5) var(--br-space-6); align-content: start; }
.th-sheet-parts > div { display: flex; flex-direction: column; gap: var(--br-space-2); min-width: 0; }
.th-sheet-parts > .wide { grid-column: 1 / -1; }
.th-point { position: fixed; z-index: 20; pointer-events: none; box-sizing: border-box; border-radius: var(--br-shape-radius-6); box-shadow: 0 0 0 2px var(--br-accent-primary), 0 0 0 4px var(--br-shade-45); }
.th-ctl > .b-track, .th-sheet-parts .b-track { flex: none; width: auto; align-self: stretch; box-sizing: border-box; }
.th-picker > label > .b-track { width: 100%; box-sizing: border-box; }

/* ---- App variants (Bridge Themes: each app on its own). An app's own ways of working that a layout can choose;
   Kit names the chosen one on the page (data-brv-<name>). Games: the game in front on a card of its own; covers that
   stay their size. */
.g-top.card > .g-hero { padding: var(--br-space-5); border-radius: var(--br-shape-radius); background: var(--br-glass-tint); border: 1px solid var(--br-glass-edge); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-glass);
  -webkit-backdrop-filter: blur(var(--br-glass-blur)) saturate(var(--br-glass-saturation)); backdrop-filter: blur(var(--br-glass-blur)) saturate(var(--br-glass-saturation)); box-sizing: border-box; }
:root[data-brv-covers="still"] .g-cover.is-selected, :root[data-brv-covers="still"] .g-page.grid .g-cover.is-selected, :root[data-brv-covers="still"] .g-cover.is-pad-focus { transform: none; }

/* ---- Keep this look? (Bridge Themes: Keep or revert.) A small card at the bottom after a theme is applied, counting
   down. Always Bridge Default (it carries .br-default, which sets every token back) and made of parts of its own that
   no skin restyles, so it can be read whatever the theme did. */
.b-keep { position: fixed; inset: 0; z-index: 100; display: grid; place-items: end center; padding: var(--br-space-6); pointer-events: none; }
.b-keep-card { pointer-events: auto; width: 440px; max-width: 100%; box-sizing: border-box; display: flex; flex-direction: column; gap: var(--br-space-2); padding: var(--br-space-5);
  border-radius: var(--br-shape-radius); background: linear-gradient(var(--br-glass-strong), var(--br-glass-strong)), var(--br-wallpaper-base); border: 1px solid var(--br-glass-edge); box-shadow: var(--br-shadow-edge-light), var(--br-shadow-float);
  color: var(--br-text-primary); font: 400 14px/20px var(--br-font-ui); text-transform: none; letter-spacing: normal; }
.b-keep-card > b { font: 600 18px/24px var(--br-font-display); }
.b-keep-card > span { color: var(--br-text-secondary); }
.b-keep-bar { display: block; height: 4px; border-radius: var(--br-shape-pill); background: var(--br-glass-inset); overflow: hidden; }
.b-keep-bar > i { display: block; height: 100%; background: var(--br-accent-primary); transition: width var(--br-motion-press) linear; }
.b-keep-actions { display: grid; grid-template-columns: 1fr 1fr; gap: var(--br-space-3); margin-top: var(--br-space-2); }
.b-keep-btn { height: var(--br-size-control); padding: 0 var(--br-space-4); border: 0; border-radius: var(--br-shape-radius); cursor: pointer; background: var(--br-glass-lift); color: var(--br-text-primary);
  box-shadow: inset 0 0 0 1px var(--br-glass-edge); font: 600 14px/20px var(--br-font-ui); }
.b-keep-btn.primary { background: var(--br-accent-primary); color: var(--br-text-on-accent); box-shadow: none; }
.b-keep-btn:hover, .b-keep-btn:focus-visible, .b-keep-btn.is-pad-focus { box-shadow: var(--br-highlight-edge); outline: none; }
