/* Re:Vault - universal theme. All colors are CSS variables so the theme is fully
   user-tweakable. Dark by default; [data-theme="light"] flips the tokens. */
:root {
	--look-backdrop: none;
	--accent: #e9c46a;
	--accent-2: #bf953f;
	--font: Verdana, Geneva, Tahoma, sans-serif;
	--fs: 13px;
	--icon: 17px;
	--ctrl: 34px;
	/* every tab is exactly this wide (see .rv-tab); --tab-w-min is the floor they
	   all shrink to together before the strip starts scrolling instead. The floor
	   has to keep a tab's fixed furniture (12px pad + favicon + 2 gaps + ✕ + 8px
	   pad = 74px) inside the cell, or a tab that HAS a favicon pushes its ✕ past
	   the cell edge and the ✕ column stops lining up. */
	--tab-w: 200px;
	--tab-w-min: 84px;

	--bg: #000;
	--surface: #0c0c0c;
	--surface-2: #161616;
	--line: #1c1c1c;
	--fg: #ededed;
	--fg-2: #cfcfcf;
	--muted: #8a8a8a;
	--muted-2: #9a9a9a;
	--danger: #ff7f7f;
	/* input and control borders (3:1); --line stays a decorative hairline */
	--line-strong: color-mix(in srgb, var(--fg) 45%, var(--surface));
	/* the accent when it is text or a focus ring, kept readable on light looks
	   (theme.js recomputes it from the picked accent) */
	--accent-ink: var(--accent);
	--on-accent: #1a1500;
	--icon-tint: var(--accent-ink);
	--new: #e0a458;
	--font-display: var(--font);
	/* corner-roundness tiers (overridden per cornerStyle by app/theme.js) */
	--radius-sm: 6px;
	--radius: 8px;
	--radius-lg: 12px;
	--radius-pill: 22px;
	/* translucent chrome surface, used only when a wallpaper is active */
	--veil: rgba(0, 0, 0, 0.5);
}
/* amber "new" markers need more weight on light pages */
:root[data-mode="light"] { --new: #8a5410; --danger: #b3261e; }
/* --- base color schemes (data-theme); --veil set on the light-mode ones ------ */
:root[data-theme="slate"] {
	--bg: #15171b; --surface: #1e2127; --surface-2: #2a2e35; --line: #333841;
	--fg: #f0f1f4; --fg-2: #ccd0d7; --muted: #9197a1; --muted-2: #a0a7b1;
}
:root[data-theme="midnight"] {
	--bg: #080d1a; --surface: #111a30; --surface-2: #1b2742; --line: #28354f;
	--fg: #e9eef8; --fg-2: #c6cfe3; --muted: #8893ad; --muted-2: #97a2bb;
}
:root[data-theme="plum"] {
	--bg: #120a1a; --surface: #1d1230; --surface-2: #291a3c; --line: #37254c;
	--fg: #efe9f5; --fg-2: #d4cae0; --muted: #9d90b0; --muted-2: #ab9ebd;
}
:root[data-theme="forest"] {
	--bg: #0a140e; --surface: #111e16; --surface-2: #1a2c20; --line: #26392c;
	--fg: #e9f2ec; --fg-2: #c8d6cd; --muted: #8a9b91; --muted-2: #9aab9f;
}
:root[data-theme="light"] {
	--bg: #f5f5f6; --surface: #ffffff; --surface-2: #ececee; --line: #dcdce0;
	--fg: #16181d; --fg-2: #33363d; --muted: #5b5e66; --muted-2: #4a4d54;
	--line-strong: #8b8e96;
	--veil: rgba(245, 245, 246, 0.62);
}
:root[data-theme="sepia"] {
	--bg: #f4efe4; --surface: #fdf9f1; --surface-2: #ece3d2; --line: #ddd2bd;
	--fg: #2a2620; --fg-2: #473f33; --muted: #625945; --muted-2: #5a5142;
	--line-strong: #8f826a; --accent-ink: #1f5fb8;
	--veil: rgba(244, 239, 228, 0.62);
}
:root[data-theme="contrast"] {
	--bg: #000000; --surface: #0a0a0a; --surface-2: #1c1c1c; --line: #9e9e9e; --line-strong: #ffffff;
	--fg: #ffffff; --fg-2: #ffffff; --muted: #e0e0e0; --muted-2: #e0e0e0; --danger: #ff9c9c; --new: #ffd27a;
	--on-accent: #000000; --veil: #000000; --look-backdrop: none;
}
/* more standard dark palettes */
:root[data-theme="crimson"] { --bg: #1a0d10; --surface: #261218; --surface-2: #341921; --line: #43232d; --fg: #f5e8eb; --fg-2: #e6c9cf; --muted: #bb8e95; --muted-2: #c99ca3; }
:root[data-theme="ocean"] { --bg: #08161c; --surface: #0f222a; --surface-2: #173039; --line: #21404b; --fg: #e7f3f6; --fg-2: #c6dde2; --muted: #8ba7af; --muted-2: #9bb7bf; }
:root[data-theme="rose"] { --bg: #1a0e15; --surface: #26141f; --surface-2: #341d2b; --line: #43283a; --fg: #f6e9f0; --fg-2: #e6cdd9; --muted: #bb909f; --muted-2: #c9a0af; }
:root[data-theme="mocha"] { --bg: #17110d; --surface: #221a14; --surface-2: #30251c; --line: #3f3024; --fg: #f1e9e0; --fg-2: #dbcdbe; --muted: #ab9b8a; --muted-2: #bbab9a; }
:root[data-theme="nord"] { --bg: #2e3440; --surface: #3b4252; --surface-2: #434c5e; --line: #4c566a; --fg: #eceff4; --fg-2: #d8dee9; --muted: #b8c0cd; --muted-2: #b8c0cd; }
:root[data-theme="dracula"] { --bg: #282a36; --surface: #343746; --surface-2: #424557; --line: #4d5068; --fg: #f8f8f2; --fg-2: #dddde2; --muted: #b0b6c6; --muted-2: #bcc0ce; }
/* Vocaloid character palettes */
:root[data-theme="miku"] { --bg: #07171a; --surface: #0e2428; --surface-2: #163337; --line: #20454a; --fg: #e6f6f5; --fg-2: #c3dedb; --muted: #88aaa6; --muted-2: #98bab6; }
:root[data-theme="teto"] { --bg: #190a0c; --surface: #261013; --surface-2: #34181c; --line: #442026; --fg: #f6e9ea; --fg-2: #e6cccf; --muted: #bb9094; --muted-2: #c9a0a3; }
:root[data-theme="rin"] { --bg: #1a1206; --surface: #261c0d; --surface-2: #342817; --line: #443521; --fg: #f6efe2; --fg-2: #e4d6bf; --muted: #b39d7a; --muted-2: #c1ac8a; }
:root[data-theme="gumi"] { --bg: #0a160e; --surface: #112015; --surface-2: #1a2e20; --line: #25402c; --fg: #e8f4ec; --fg-2: #cbdecf; --muted: #8ca895; --muted-2: #9cb8a5; }
:root[data-theme="sasuke"] { --bg: #0c0e1a; --surface: #161a2c; --surface-2: #2d3141; --line: #454856; --fg: #e4e6f1; --fg-2: #cdd2e6; --muted: #949ab5; --muted-2: #9ca1bb; }
:root[data-theme="sakura"] { --bg: #1a0e14; --surface: #28141e; --surface-2: #3e2c35; --line: #53434b; --fg: #f5e3ea; --fg-2: #ecccd8; --muted: #c191a0; --muted-2: #c79caa; }
:root[data-theme="kakashi"] { --bg: #12161a; --surface: #1c2228; --surface-2: #33383e; --line: #494e53; --fg: #e4e7ea; --fg-2: #cdd4d8; --muted: #9ba3a8; --muted-2: #9ca4a9; }
:root[data-theme="itachi"] { --bg: #160709; --surface: #220c10; --surface-2: #382428; --line: #4e3d40; --fg: #f2dfe1; --fg-2: #e8c4c8; --muted: #bd868c; --muted-2: #c49298; }
:root[data-theme="hinata"] { --bg: #14101c; --surface: #1f1830; --surface-2: #352f45; --line: #4c4659; --fg: #eae5f3; --fg-2: #d8d0ea; --muted: #a89fc4; --muted-2: #b1a9ca; }
:root[data-theme="jeffy"] { --bg: #161806; --surface: #22260d; --surface-2: #383c25; --line: #4e513d; --fg: #eceed9; --fg-2: #dde0ba; --muted: #aaad78; --muted-2: #b3b586; }
:root[data-theme="woodland"] { --bg: #0c160e; --surface: #142017; --surface-2: #2c362e; --line: #434d45; --fg: #e2ece5; --fg-2: #cbdccf; --muted: #8ba894; --muted-2: #97b19f; }
:root[data-theme="tide"] { --bg: #08161e; --surface: #0f2230; --surface-2: #273845; --line: #3f4e59; --fg: #e0ecf0; --fg-2: #c6dde4; --muted: #88a7b0; --muted-2: #94b0b8; }
:root[data-theme="alpine"] { --bg: #0e131c; --surface: #182234; --surface-2: #2f3848; --line: #464e5d; --fg: #e3e7ef; --fg-2: #ccd4e2; --muted: #9aa4b7; --muted-2: #9ca5b8; }
:root[data-theme="autumn"] { --bg: #1a1108; --surface: #271a0d; --surface-2: #3d3125; --line: #52483d; --fg: #f5e7d8; --fg-2: #ecd4b8; --muted: #bd9a74; --muted-2: #c4a482; }
:root[data-theme="bloom"] { --bg: #170f14; --surface: #241620; --surface-2: #3a2d36; --line: #50454d; --fg: #f5e3e8; --fg-2: #ecccd6; --muted: #c191a0; --muted-2: #c79caa; }
:root[data-theme="jdm"] { --bg: #160a0c; --surface: #221012; --surface-2: #38282a; --line: #4e4041; --fg: #f1e1e3; --fg-2: #e6c9cc; --muted: #bb8e92; --muted-2: #c2999d; }
:root[data-theme="lambo"] { --bg: #121706; --surface: #1d260c; --surface-2: #343c24; --line: #4a513d; --fg: #ecefd9; --fg-2: #dde2ba; --muted: #a8ad77; --muted-2: #b1b585; }
:root[data-theme="ferrari"] { --bg: #1a0708; --surface: #270c0e; --surface-2: #3d2426; --line: #523d3e; --fg: #f2dfe0; --fg-2: #e8c4c6; --muted: #bd868a; --muted-2: #c49296; }
:root[data-theme="gtr"] { --bg: #0e1418; --surface: #182226; --surface-2: #2f383c; --line: #464e51; --fg: #e4e8eb; --fg-2: #cdd6da; --muted: #9ba4aa; --muted-2: #99a2a8; }
:root[data-theme="chalkboard"] { --bg: #0d1410; --surface: #161f1a; --surface-2: #2d3531; --line: #454c48; --fg: #e3e8e5; --fg-2: #ccd6cf; --muted: #96a19c; --muted-2: #98a29d; }
:root[data-theme="notebook"] { --bg: #eef2fb; --surface: #ffffff; --surface-2: #f4f6fb; --line: #d5dbe6; --line-strong: #7f899b; --fg: #1f2733; --accent-ink: #2b6cc4; --fg-2: #2a3340; --muted: #586472; --muted-2: #5f6a76; --veil: rgba(238,242,251,0.62); }
:root[data-theme="library"] { --bg: #16110b; --surface: #221a12; --surface-2: #38312a; --line: #4e4841; --fg: #ebe4da; --fg-2: #dbcdbb; --muted: #ab9b80; --muted-2: #b3a58d; }
:root[data-theme="keystone-cat"] { --bg: #121214; --surface: #1c1c20; --surface-2: #2a2a2f; --line: #38383f; --fg: #f1f1f4; --fg-2: #d2d2d8; --muted: #92929a; --muted-2: #9d9da5; }
:root[data-theme="vista"] { --bg: #0a1612; --surface: #112019; --surface-2: #293630; --line: #414d47; --fg: #e1ece5; --fg-2: #c8dccf; --muted: #88a896; --muted-2: #94b1a1; }
:root[data-theme="canyon"] { --bg: #190f08; --surface: #261810; --surface-2: #3c2f28; --line: #514640; --fg: #f5e4d4; --fg-2: #ecceb0; --muted: #bd9870; --muted-2: #c4a27e; }
:root[data-theme="coast"] { --bg: #08141e; --surface: #0f2030; --surface-2: #273645; --line: #3f4d59; --fg: #e0eaf0; --fg-2: #c6d8e4; --muted: #88a0b0; --muted-2: #94aab8; }
:root[data-theme="skyline"] { --bg: #0a0f1c; --surface: #131a2c; --surface-2: #2b3141; --line: #424856; --fg: #e4e7f0; --fg-2: #cdd4e4; --muted: #949cb2; --muted-2: #98a1b5; }
:root[data-theme="neon"] { --bg: #0e0a16; --surface: #181122; --surface-2: #2f2938; --line: #46414e; --fg: #e8e3f1; --fg-2: #d6cce6; --muted: #9a8cb3; --muted-2: #a498bb; }
:root[data-theme="synthwave"] { --bg: #150a1e; --surface: #20102e; --surface-2: #362843; --line: #4d4058; --fg: #f1e3ee; --fg-2: #e6cce0; --muted: #b48cb0; --muted-2: #bc98b8; }
:root[data-theme="vaporwave"] { --bg: #140e1e; --surface: #1f1530; --surface-2: #352c45; --line: #4c4459; --fg: #ece3f1; --fg-2: #dccce6; --muted: #a896bd; --muted-2: #b1a1c4; }
:root[data-theme="lofi"] { --bg: #14100c; --surface: #201913; --surface-2: #36302b; --line: #4d4742; --fg: #ece3da; --fg-2: #ddccbb; --muted: #a89684; --muted-2: #b1a190; }
/* Spooky (seasonal, Spooky Week): a dusky plum night with warm parchment text and a low
   pumpkin glow along the bottom edge. */
:root[data-theme="spooky"] { --bg: #120c17; --surface: #1c1423; --surface-2: #2c2134; --line: #43354c; --fg: #f4ebdf; --fg-2: #e6d5c2; --muted: #b8a2b4; --muted-2: #c2adbd; --veil: rgba(18, 12, 23, 0.55);
	--look-backdrop: radial-gradient(60% 45% at 82% 6%, rgba(244, 226, 190, 0.1), rgba(244, 226, 190, 0) 70%), radial-gradient(120% 60% at 50% 115%, rgba(240, 138, 36, 0.16), rgba(240, 138, 36, 0) 62%), linear-gradient(180deg, #1a1122 0%, #130d19 60%, #0f0a13 100%); }
/* Frutiger Aero - bright sky/aqua glass (light). Tokens here; the glossy gel
   surfaces, sky gradient, and frosted glass are in the scoped block at EOF. */
:root[data-theme="frutiger"] { --bg: #bfe6ff; --surface: #f4fbff; --surface-2: #ddf1fe; --line: #aed7f1; --line-strong: #4f7f99; --fg: #0c2c3e; --fg-2: #1f5066; --muted: #2d5367; --muted-2: #29495c; --accent-ink: #0b5f58;
	--look-backdrop: linear-gradient(180deg, #9fd8ff 0%, #cdecff 46%, #e9fbe9 100%); --veil: rgba(231, 247, 255, 0.5); }
/* Frutiger Aero Dark - deep teal "Aero glass" (dark). Tokens here; glossy glass +
   aqua aurora backdrop are in the scoped block at EOF. */
:root[data-theme="frutiger-dark"] { --bg: #07151c; --surface: #0e2731; --surface-2: #163540; --line: #224552; --fg: #e6f6fb; --fg-2: #c2e3ec; --muted: #84a9b4; --muted-2: #94b8c2; --veil: rgba(10, 30, 38, 0.5);
	--look-backdrop: radial-gradient(120% 85% at 50% -8%, rgba(34, 211, 238, 0.18), rgba(34, 211, 238, 0) 58%), linear-gradient(180deg, #0b2a35 0%, #08191f 55%, #06121a 100%); }
/* Bedazzled Vault - glossy black-and-gold luxe take on the default Vault (dark).
   Tokens here; the warm gradient backdrop + gold gel surfaces are in the scoped
   block at EOF. */
:root[data-theme="bedazzled"] {
	--bg: #100d09; --surface: #18130c; --surface-2: #251d12; --line: #3a2d1c; --line-strong: #7a6440;
	--fg: #ece3cf; --fg-2: #ddd0b6; --muted: #ab9b7c; --muted-2: #bbab8c; --veil: rgba(18, 13, 7, 0.5);
	--icon-tint: #d9b766; --on-accent: #2a1e05; --new: #e0a458;
	--look-backdrop: radial-gradient(130% 90% at 50% -10%, rgba(233, 196, 106, 0.12), rgba(233, 196, 106, 0) 60%), linear-gradient(180deg, #1e170e 0%, #120e09 55%, #0d0a07 100%);
}
/* Zen: sumi ink on a warm dark ground, rice-paper text, a vermilion seal, sage for quiet marks */
:root[data-theme="zen"] {
	--bg: #141311; --surface: #1c1a17; --surface-2: #25221e; --line: #3a352e; --line-strong: #7a7062;
	--fg: #ebe5d8; --fg-2: #d3ccbd; --muted: #a39b8b; --muted-2: #b1aa9b; --veil: rgba(20, 19, 17, 0.55);
	--sage: #93a98d; --icon-tint: var(--sage); --new: var(--sage);
	--font-display: "Shippori Mincho", "Iowan Old Style", Georgia, "Times New Roman", serif;
	--look-backdrop: radial-gradient(120% 70% at 50% -10%, rgba(120, 60, 40, 0.1), rgba(120, 60, 40, 0) 60%), linear-gradient(180deg, #171512 0%, #141311 60%, #100f0d 100%);
}
:root[data-theme="zen-paper"] {
	--bg: #f3eee3; --surface: #faf7f0; --surface-2: #ebe4d5; --line: #d6ccb8; --line-strong: #8c8170;
	--fg: #23201b; --fg-2: #3d3931; --muted: #655e51; --muted-2: #575146; --veil: rgba(243, 238, 227, 0.6);
	--sage: #556c50; --icon-tint: var(--sage); --new: var(--sage); --accent-ink: #b0392b; --on-accent: #ffffff;
	--font-display: "Shippori Mincho", "Iowan Old Style", Georgia, "Times New Roman", serif;
	--look-backdrop: radial-gradient(120% 70% at 50% -10%, rgba(180, 130, 100, 0.08), rgba(180, 130, 100, 0) 60%), linear-gradient(180deg, #f6f2e9 0%, #f3eee3 60%, #ece6d9 100%);
}
:root[data-density="compact"] { --fs: 12px; --ctrl: 30px; }
:root[data-animations="off"] * { transition: none !important; animation-duration: 0.001s !important; }

/* --- Performance / Lite mode (data-perf="on") --------------------------------
   Auto-enabled on low-end devices (Data Saver / <=2GB RAM / <=2 cores) and
   forceable in Settings. Strips the compositor-heavy effects that jank on
   Chromebooks and integrated GPUs - frosted-glass backdrop-filter, wallpaper
   gaussian blur, big shadows - and neutralizes transitions/animations. The UI
   stays fully usable, just flatter and cheaper to paint. */
:root[data-perf="on"] *,
:root[data-perf="on"] *::before,
:root[data-perf="on"] *::after {
	-webkit-backdrop-filter: none !important;
	backdrop-filter: none !important;
	transition: none !important;
	animation-duration: 0.001s !important;
	animation-delay: 0s !important;
	box-shadow: none !important;
	text-shadow: none !important;
}
/* Drop the (very expensive) wallpaper gaussian blur; the dim scrim stays. */
:root[data-perf="on"] .rv-wallpaper::before { filter: none !important; }
/* Keep the loading feedback readable even with animations neutralized. */
:root[data-perf="on"] .rv-spin { animation: rvspin 0.9s linear infinite !important; }
:root[data-perf="on"] .rv-pipe span { animation-duration: 1.6s !important; }
/* respect the OS reduced-motion preference (kills transitions; keeps the loading
   feedback animations, just slower) */
@media (prefers-reduced-motion: reduce) {
	:root:not([data-animations="off"]) * { transition-duration: 0.01ms !important; }
	.rv-spin { animation-duration: 1.3s !important; }
	.rv-pipe span { animation-duration: 2.4s !important; }
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; background: var(--bg); overflow: hidden; }
/* font-size-adjust normalizes apparent size across faces (different fonts have
   different x-heights, so some looked smaller); the value tracks Verdana's aspect
   so the default is unchanged while smaller-x-height fonts grow to match. It also
   steadies the fallback->webfont swap (less CLS). */
body { font-family: var(--font); font-size: var(--fs); color: var(--fg-2); font-size-adjust: 0.545; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
::selection { background: #2a2a2a; color: #fff; }
input::placeholder, textarea::placeholder { color: var(--muted); opacity: 1; }
@keyframes rvspin { to { transform: rotate(360deg); } }

button { cursor: pointer; font-family: inherit; color: inherit; -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
button[disabled] { cursor: default; }
:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: 3px; }
a { color: var(--accent-ink); }

.rv-root { display: flex; flex-direction: column; height: 100vh; width: 100vw; background: var(--bg); overflow: hidden; user-select: none; -webkit-user-select: none; }
/* iPhone and iPad: 100vh is the height with Safari's bars hidden, so the bottom of the app sat
   under them; dvh follows the bars. viewport-fit=cover also puts the notch and the home bar over
   the page, so keep the app inside the safe area (0 everywhere else). */
@supports (height: 100dvh) { .rv-root { height: 100dvh; } }
.rv-root { padding: 0 env(safe-area-inset-right, 0px) env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px); }
/* iOS zooms the page into any field whose text is under 16px and leaves it zoomed. :root lifts
   this over the one-class field rules below; -webkit-touch-callout only exists on iOS. */
@supports (-webkit-touch-callout: none) {
	@media (pointer: coarse) { :root :is(input:not([type="checkbox"], [type="radio"], [type="range"], [type="color"]), textarea, select) { font-size: max(16px, 1em); } }
}

/* tab strip */
.rv-tabstrip { display: flex; align-items: flex-end; height: 36px; background: var(--bg); border-bottom: 1px solid var(--line); }
.rv-brand { display: flex; align-items: center; gap: 7px; height: 36px; padding: 0 10px 0 10px; font-size: var(--fs); font-weight: 600; color: var(--fg); flex: none; }
.rv-brand #rv-logo { display: inline-flex; align-items: center; justify-content: center; width: 19px; height: 19px; flex: none; } /* reserve space so the JS-injected logo can't shift the brand row */
.rv-brand svg { width: 19px; height: 19px; flex: none; }
/* The status button (app/status.js): a shape per state, a word only when something is wrong. */
:root { --status-ok: #27c093; --status-wait: #d6a23a; --status-on: #06140e; }
:root[data-mode="light"] { --status-ok: #0d7a52; --status-wait: #8a5a00; --status-on: #fff; }
.rv-nav.rv-status { width: auto; min-width: var(--ctrl); gap: 6px; padding: 0 6px; color: var(--muted); }
.rv-status[hidden] { display: none; }
.rv-status-glyph { display: inline-flex; width: 14px; height: 14px; }
.rv-status-glyph svg { width: 14px; height: 14px; }
.rv-status[data-state="ok"], .rv-status[data-state="auto"] { color: var(--status-ok); }
.rv-status[data-state="connecting"], .rv-status[data-state="wait"] { color: var(--status-wait); }
.rv-status[data-state="down"] { color: var(--danger); }
.rv-status[data-state="offline"] { color: var(--muted-2); }
.rv-status-text { display: none; font-size: 12px; font-weight: 600; color: var(--fg); }
@media (min-width: 1100px) { .rv-status[data-state="down"] .rv-status-text, .rv-status[data-state="wait"] .rv-status-text, .rv-status[data-state="offline"] .rv-status-text { display: inline; } }
.rv-status[data-state="connecting"] .rv-status-glyph svg { animation: rv-status-spin 2.4s linear infinite; }
@keyframes rv-status-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .rv-status .rv-status-glyph svg { animation: none !important; } }
:root[data-perf="on"] .rv-status .rv-status-glyph svg, :root[data-animations="off"] .rv-status .rv-status-glyph svg { animation: none; }
.rv-status:hover { background: var(--surface-2); }
.rv-statp { position: fixed; z-index: 330; width: min(340px, calc(100vw - 16px)); padding: 14px; background: var(--surface); color: var(--fg-2); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: 0 16px 46px rgba(0, 0, 0, 0.5); font-size: 13px; }
.rv-statp[hidden] { display: none; }
.rv-statp-h { margin: 0 0 6px; font-size: 15px; color: var(--fg); }
.rv-statp-h3 { margin: 0 0 4px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted-2); }
.rv-statp-p { margin: 0 0 6px; line-height: 1.45; }
.rv-statp-muted { color: var(--muted-2); }
.rv-statp-sec { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.rv-statp-row { display: flex; flex-wrap: wrap; gap: 6px; }
.rv-statp-foot { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
/* The strip asks for exactly (tab count x --tab-w) and shrinks from there, so a
   tab's width never depends on how long its title is. Sizing it `auto` instead
   would collapse each tab back to its own content width (a shrinkable flex item
   contributes only its max-content size), which is precisely what made tabs
   ragged. --tab-n is set per render in app/view.js. */
.rv-tabs { display: flex; align-items: flex-end; flex: 0 1 calc(var(--tab-w) * var(--tab-n, 1)); overflow-x: auto; overflow-y: hidden; min-width: var(--tab-w); scrollbar-width: none; -ms-overflow-style: none; } /* reserve one tab's width so the New-tab button doesn't shift when the first tab hydrates */
.rv-tabs::-webkit-scrollbar { display: none; } /* 36px strip - no room for the global 11px bar */
/* Uniform tabs: an identical flex basis + shrink factor on every tab means they
   only ever resize TOGETHER, so each ✕ sits at the same offset in every tab and
   closing a run of tabs is repeated clicks in one spot (the survivors slide into
   the exact slot the closed tab left). Past --tab-w-min the strip scrolls rather
   than squeezing the ✕ down to nothing. */
/* minimal active tab: no top border, just a stronger background fill */
.rv-tab { display: flex; align-items: center; gap: 7px; height: 32px; padding: 0 8px 0 12px; flex: 0 1 var(--tab-w); max-width: var(--tab-w); min-width: var(--tab-w-min); cursor: pointer; font-size: var(--fs); color: var(--muted); background: transparent; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.rv-tab:hover { background: var(--surface-2); color: var(--fg-2); }
.rv-tab.active { color: var(--fg); background: var(--surface); }
.rv-tab-favicon { width: 16px; height: 16px; flex: none; background-size: contain; background-repeat: no-repeat; background-position: center; border-radius: 3px; }
.rv-tab-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-tab-close { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: 0; background: transparent; border-radius: var(--radius-sm); flex: none; color: var(--muted); touch-action: manipulation; -webkit-tap-highlight-color: transparent; }
.rv-tab-close:hover { background: var(--surface-2); color: var(--fg); }
.rv-newtab { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; margin: 0 4px 3px 5px; border: 0; background: transparent; border-radius: var(--radius-sm); flex: none; }
.rv-newtab svg { width: var(--icon); height: var(--icon); }
.rv-newtab:hover { background: var(--surface); }
.rv-spacer { flex: 1; }
/* Phones / split-screen: same uniform grid, just a narrower cell. */
@media (max-width: 560px) { :root { --tab-w: 148px; } }

/* nav bar */
.rv-navbar { display: flex; align-items: center; gap: 2px; height: 44px; background: var(--bg); border-bottom: 1px solid var(--line); padding: 0 8px; }
.rv-nav { display: flex; align-items: center; justify-content: center; width: var(--ctrl); height: var(--ctrl); border: 0; background: transparent; border-radius: var(--radius-sm); flex: none; color: var(--muted-2); }
.rv-nav svg { width: var(--icon); height: var(--icon); }
.rv-nav:hover { background: var(--surface); }
.rv-nav:active { background: var(--surface-2); }
.rv-nav[disabled] { opacity: 0.35; }
.rv-nav[disabled]:hover { background: transparent; }
.rv-omnibox { flex: 1; display: flex; align-items: center; height: 32px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 0 11px; gap: 9px; margin: 0 6px; cursor: text; }
.rv-omnibox > svg { width: 15px; height: 15px; flex: none; color: var(--muted); }
.rv-omnibox input { flex: 1; height: 100%; border: 0; background: transparent; outline: none; color: var(--fg); font-family: inherit; font-size: var(--fs); user-select: text; -webkit-user-select: text; }
.rv-spin { width: 14px; height: 14px; border: 1.5px solid var(--line); border-top-color: var(--accent); border-radius: 50%; animation: rvspin 0.7s linear infinite; flex: none; }

/* extensions button (with an enabled-count badge) + incognito indicator */
.rv-ext { position: relative; }
.rv-ext-count { position: absolute; top: 3px; right: 3px; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 8px; background: var(--accent); color: var(--on-accent); font-size: 9px; font-weight: 700; line-height: 14px; text-align: center; box-shadow: 0 0 0 2px var(--bg); }
.rv-incognito { color: var(--accent-ink); }
.rv-incognito:hover { background: var(--surface); }

/* extensions panel (toolbar dropdown) */
/* extension buttons beside the address bar (app/ext-bar.js) */
.rv-extbar { display: flex; align-items: center; gap: 2px; }
.rv-extbar[hidden] { display: none; }
.rv-extbtn { position: relative; }
.rv-extbtn svg { width: var(--icon); height: var(--icon); }
.rv-extbtn-label { display: none; }
.rv-extbtn[aria-pressed="true"] { color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 14%, transparent); }
.rv-extbtn-busy::after { content: ""; position: absolute; left: 50%; bottom: 3px; width: 12px; height: 3px; margin-left: -6px; border-radius: 2px; background: linear-gradient(90deg, var(--accent-ink) 0 3px, transparent 3px 4.5px, var(--accent-ink) 4.5px 7.5px, transparent 7.5px 9px, var(--accent-ink) 9px 12px); animation: rv-bars 1.1s ease-in-out infinite alternate; }
@keyframes rv-bars { to { transform: scaleY(1.9); } }
@media (prefers-reduced-motion: reduce) { .rv-extbtn-busy::after { animation: none; } }
:root[data-perf="on"] .rv-extbtn-busy::after, :root[data-animations="off"] .rv-extbtn-busy::after { animation: none; }
.rv-extmenu { position: fixed; z-index: 340; min-width: 200px; max-width: min(300px, calc(100vw - 16px)); padding: 4px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: 0 12px 34px rgba(0, 0, 0, 0.45); }
.rv-extmenu-info { margin: 4px 8px 6px; color: var(--fg-2); font-size: 12.5px; line-height: 1.4; }
.rv-extmenu-item { display: block; width: 100%; min-height: 34px; padding: 0 10px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--fg); font-size: 13px; text-align: left; }
.rv-extmenu-item:hover, .rv-extmenu-item:focus-visible { background: var(--surface-2); }
@media (any-pointer: coarse) { .rv-extmenu-item { min-height: 44px; } }
.rv-extp-ctl { display: flex; align-items: center; gap: 6px; flex: none; }
.rv-extp-pin { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: 1px solid transparent; border-radius: var(--radius-sm); background: transparent; color: var(--muted); }
.rv-extp-pin svg { width: 14px; height: 14px; }
.rv-extp-pin[aria-pressed="true"] { color: var(--accent-ink); border-color: color-mix(in srgb, var(--accent) 40%, transparent); }
@media (forced-colors: active) { .rv-extbtn[aria-pressed="true"], .rv-extp-pin[aria-pressed="true"] { outline: 2px solid Highlight; } }
.rv-extp { position: fixed; z-index: 320; width: min(340px, 94vw); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: 0 16px 46px rgba(0, 0, 0, 0.5); overflow: hidden; display: flex; flex-direction: column; max-height: 76vh; }
.rv-extp[hidden] { display: none; }
.rv-extp-head { padding: 12px 14px 10px; border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: 2px; }
.rv-extp-head strong { font-size: 14px; color: var(--fg); }
.rv-extp-sub { font-size: 11.5px; color: var(--muted); }
.rv-extp-body { overflow-y: auto; padding: 4px 0; }
.rv-extp-cat { padding: 10px 14px 4px; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); }
.rv-extp-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 14px; }
.rv-extp-row:hover { background: var(--surface-2); }
.rv-extp-ic { flex: none; width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; color: var(--muted-2); }
.rv-extp-row.on .rv-extp-ic { color: var(--accent-ink); }
.rv-extp-ic svg { width: 18px; height: 18px; }
.rv-extp-txt { flex: 1; min-width: 0; }
.rv-extp-name { font-size: 13px; color: var(--fg); }
.rv-extp-desc { font-size: 11.5px; color: var(--muted); line-height: 1.35; margin-top: 1px; }
.rv-extp-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.rv-extp-act { font-size: 11.5px; color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 12%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 32%, transparent); border-radius: var(--radius-pill); padding: 3px 10px; cursor: pointer; }
.rv-extp-act:hover { background: color-mix(in srgb, var(--accent) 22%, transparent); }
.rv-extp-foot { border-top: 1px solid var(--line); padding: 8px 10px; }
.rv-extp-manage { width: 100%; font-size: 12.5px; color: var(--fg-2); background: transparent; border: 1px solid var(--line); border-radius: var(--radius); padding: 8px; cursor: pointer; }
.rv-extp-manage:hover { border-color: var(--accent-2); color: var(--fg); }
/* toggle switch (app-side copy of the settings switch, for the panel) */
.rv-switch { flex: none; width: 42px; height: 24px; border-radius: 13px; border: 1px solid var(--line-strong); background: var(--surface-2); position: relative; transition: background 0.15s, border-color 0.15s; cursor: pointer; }
.rv-switch::after { content: ""; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: var(--muted-2); transition: transform 0.15s, background 0.15s; }
.rv-switch[data-on="1"] { background: var(--accent); border-color: var(--accent); }
.rv-switch[data-on="1"]::after { transform: translateX(18px); background: var(--on-accent); }
.rv-switch-sm { width: 38px; height: 22px; margin-top: 2px; }
.rv-switch-sm::after { width: 16px; height: 16px; }
.rv-switch-sm[data-on="1"]::after { transform: translateX(16px); }

/* content */
.rv-content { position: relative; flex: 1; background: var(--bg); }
/* dark (not white) background so a navigating iframe never flashes white */
.rv-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: var(--bg); }
.rv-frame[hidden] { display: none; }

/* start screen */
.rv-start { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 26px; background: var(--bg); padding: 24px; }
.rv-clock { font-size: 58px; color: var(--fg); font-variant-numeric: tabular-nums; letter-spacing: 1px; width: 100%; text-align: center; } /* full-width box so the ticking time can't resize/re-center (CLS) */
.rv-shortcuts { display: flex; gap: 28px; }
.rv-shortcut { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.rv-shortcut-btn { display: flex; align-items: center; justify-content: center; width: 66px; height: 66px; border: 1px solid var(--line); background: var(--bg); border-radius: 50%; cursor: pointer; color: var(--icon-tint); }
.rv-shortcut-btn svg { width: 26px; height: 26px; }
.rv-shortcut-btn:hover { border-color: var(--accent-2); }
.rv-shortcut-btn:active { border-color: var(--accent); }
.rv-shortcut span { font-size: var(--fs); color: var(--fg-2); }
/* no iOS callout or text selection on a press-and-hold, which opens the tile's own menu */
.rv-shortcut-btn { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.rv-shortcut-all .rv-shortcut-btn { border-style: dashed; border-color: var(--line-strong); }
.rv-shortcut { position: relative; }
.rv-shortcut-note { position: absolute; top: -8px; left: 50%; transform: translateX(-50%); padding: 1px 7px; border: 1px solid var(--accent); border-radius: 999px; background: var(--surface-2); color: var(--fg); font-size: 10.5px; font-weight: 600; line-height: 15px; white-space: nowrap; pointer-events: none; }
.rv-shortcut-note[hidden] { display: none; }
/* Study Hall's unread dot: a ring in the page color keeps it clear of the tile's icon. */
.rv-shortcut-dot { position: absolute; top: 2px; right: calc(50% - 30px); width: 10px; height: 10px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px var(--bg); pointer-events: none; }
.rv-shortcut-dot[hidden] { display: none; }

.rv-trust { color: var(--muted); font-size: 12px; line-height: 1.6; text-align: center; margin: 0; }
.rv-trust a { white-space: nowrap; color: var(--muted-2); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--line); }
.rv-trust a:hover { color: var(--fg); }

/* folder view */
.rv-folder { position: absolute; inset: 0; display: flex; flex-direction: column; background: var(--bg); }
.rv-folder-head { display: flex; align-items: center; gap: 10px; padding: 18px 24px 12px; flex: none; border-bottom: 1px solid var(--line); }
.rv-folder-head svg { width: 21px; height: 21px; flex: none; color: var(--accent-ink); }
.rv-folder-title { font-size: 18px; font-weight: 600; color: var(--fg); letter-spacing: 0.3px; }
.rv-folder-search { margin-left: auto; height: 32px; width: clamp(160px, 30vw, 320px); border: 1px solid var(--line); background: var(--bg); color: var(--fg); border-radius: var(--radius); padding: 0 12px; font: inherit; font-size: 13px; outline: none; user-select: text; -webkit-user-select: text; }
.rv-folder-search:focus { border-color: var(--accent-ink); }
.rv-folder-search:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
.rv-folder-empty { flex: 1; display: flex; align-items: center; justify-content: center; color: var(--muted); font-size: var(--fs); text-align: center; padding: 20px; }
/* grid-auto-rows:max-content keeps each row at its cards' content height - without
   it, overflow:hidden cards get an automatic min-size of 0 and the rows collapse
   to slivers (whole grid scrolls / shrinks them away). */
.rv-grid { flex: 1; overflow: auto; -webkit-overflow-scrolling: touch; display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); grid-auto-rows: max-content; gap: 16px; padding: 18px 24px 26px; align-content: start; }
.rv-card { display: flex; flex-direction: column; cursor: pointer; border: 1px solid var(--line); background: var(--surface); border-radius: var(--radius); overflow: hidden; transition: transform 0.12s ease, border-color 0.12s ease; }
.rv-card:hover { border-color: var(--accent-2); transform: translateY(-2px); }
.rv-card:active { transform: translateY(0); }
/* square image area, image shown whole (not cropped) - used by Books + Worksheets */
.rv-card-imgwrap { position: relative; aspect-ratio: 1 / 1; width: 100%; flex: none; background: linear-gradient(135deg, #1a1813, #0b0b0b); overflow: hidden; }
.rv-card-img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; object-fit: contain; padding: 6%; }
.rv-card-fallback { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 8px; text-align: center; font-size: 12px; line-height: 1.3; color: #bdb6a6; } /* the cover behind it is always dark */
.rv-card-title { padding: 10px 12px; font-size: var(--fs); color: var(--fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* error overlay */
.rv-error { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: var(--bg); padding: 24px; }
.rv-err-card { max-width: 440px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.rv-err-icon { width: 56px; height: 56px; display: flex; align-items: center; justify-content: center; border-radius: 50%; border: 1px solid var(--line); background: var(--surface); }
.rv-err-title { font-size: 19px; color: var(--fg); font-weight: 600; }
.rv-err-msg { color: var(--muted-2); line-height: 1.5; }
.rv-err-actions { display: flex; gap: 10px; margin-top: 6px; flex-wrap: wrap; justify-content: center; }
.rv-err-details { margin-top: 10px; font-size: 12px; color: var(--muted); text-align: left; width: 100%; max-width: 360px; }
.rv-err-details summary { cursor: pointer; text-align: center; list-style-position: inside; }
.rv-err-details dl { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin: 10px 0 6px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.rv-err-details dt { color: var(--muted); }
.rv-err-details dd { margin: 0; color: var(--fg-2); overflow-wrap: anywhere; }
.rv-err-another { background: none; border: 0; padding: 4px 0; color: var(--accent); font-size: 12px; cursor: pointer; text-decoration: underline; }
.rv-wait { display: flex; flex-direction: column; align-items: center; gap: 6px; max-width: 340px; text-align: center; }
.rv-wait[hidden] { display: none; }
.rv-wait-title { color: var(--fg); font-size: 15px; font-weight: 600; margin: 0; }
.rv-wait-msg { color: var(--muted-2); font-size: 13px; margin: 0; }
.rv-wait-actions { display: flex; gap: 10px; margin-top: 8px; flex-wrap: wrap; justify-content: center; }
.rv-loader[data-wait] .rv-loader-skip { display: none; }
.rv-loader[data-wait="server"] .rv-loader-label, .rv-loader[data-wait="online"] .rv-loader-label { display: none; }

/* buttons */
.rv-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: 34px; padding: 0 14px; border: 1px solid var(--line); background: var(--surface); color: var(--fg); border-radius: var(--radius); font-size: var(--fs); }
.rv-btn:hover { border-color: var(--accent-2); }
.rv-btn-primary { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 600; }
.rv-btn-primary:hover { background: var(--accent-2); }
.rv-btn-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, var(--line)); }

/* scrollbars */
*::-webkit-scrollbar { width: 11px; height: 11px; }
*::-webkit-scrollbar-thumb { background: var(--line); border-radius: var(--radius-sm); border: 3px solid var(--bg); }
*::-webkit-scrollbar-thumb:hover { background: var(--accent-2); }

/* toolbar star */
.rv-star.active { color: var(--accent-ink); }
.rv-star.active svg path { fill: var(--accent); }

/* bookmarks bar */
.rv-bookmarksbar { display: flex; align-items: center; gap: 3px; height: 34px; padding: 0 8px; background: var(--bg); border-bottom: 1px solid var(--line); overflow-x: auto; flex: none; scrollbar-width: none; }
.rv-bookmarksbar::-webkit-scrollbar { height: 0; }
.rv-bm-item { height: 25px; max-width: 180px; padding: 0 9px; border: 0; background: transparent; color: var(--fg-2); border-radius: var(--radius-sm); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: none; }
.rv-bm-item:hover { background: var(--surface); color: var(--fg); }
.rv-bm-empty { color: var(--muted); font-size: 12px; padding: 0 8px; }

/* start-screen dashboard - anchored to the top so any post-load content settle
   extends downward (no re-centering layout shift) */
.rv-start { overflow: auto; justify-content: flex-start; padding: clamp(28px, 9vh, 90px) 24px 36px; }
.rv-start-inner { display: flex; flex-direction: column; align-items: center; gap: 20px; width: 100%; max-width: 720px; margin: 0 auto; }
.rv-greeting { font-size: 15px; color: var(--muted-2); min-height: 19px; }
.rv-clock { font-size: clamp(40px, 7vw, 56px); line-height: 1.3; margin-bottom: -6px; } /* Sora's own line height, fixed so the web-font swap cannot move the page (CLS) */
.rv-date { font-size: 14px; color: var(--muted); margin-top: -6px; min-height: 18px; }
.rv-startsearch { display: flex; align-items: center; gap: 9px; width: min(560px, 92%); height: 44px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-pill); padding: 0 17px; }
.rv-startsearch svg { width: 16px; height: 16px; color: var(--muted); flex: none; }
.rv-startsearch input { flex: 1; height: 100%; border: 0; background: transparent; outline: none; color: var(--fg); font: inherit; font-size: 14px; user-select: text; -webkit-user-select: text; }
.rv-startsearch:focus-within, .rv-omnibox:focus-within { border-color: var(--accent-ink); box-shadow: 0 0 0 1px var(--accent-ink); }
.rv-shortcuts { flex-wrap: wrap; justify-content: center; gap: 20px 26px; min-height: 92px; align-content: center; }
/* "Restore N tabs": one fixed-height row, so the pre-paint can hold its place (data-restore). */
.rv-restore { display: flex; align-items: center; gap: 10px; width: min(560px, 92%); height: 44px; padding: 0 4px 0 4px; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius-pill); }
.rv-restore[hidden] { display: none; }
:root[data-restore] .rv-restore[hidden] { display: flex; visibility: hidden; }
.rv-restore-go { display: inline-flex; align-items: center; gap: 7px; flex: none; height: 34px; padding: 0 14px; border: 1px solid var(--accent); border-radius: var(--radius-pill); background: var(--accent); color: var(--on-accent); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; }
.rv-restore-go svg { width: 15px; height: 15px; }
.rv-restore-go:hover { background: var(--accent-2); border-color: var(--accent-2); }
.rv-restore-line { flex: 1; min-width: 0; font-size: 12.5px; color: var(--muted-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rv-restore-x { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 34px; height: 34px; border: 0; border-radius: 50%; background: transparent; color: var(--fg-2); cursor: pointer; }
.rv-restore-x svg { width: 12px; height: 12px; }
.rv-restore-x:hover { background: var(--surface-2); color: var(--fg); }
.rv-restore :focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.rv-recents { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; max-width: 680px; }
.rv-recent { display: inline-flex; align-items: center; height: 30px; max-width: 220px; border: 1px solid var(--line); background: var(--surface); border-radius: 15px; overflow: hidden; }
.rv-recent:hover { border-color: var(--accent-2); }
.rv-recent-go { max-width: 180px; height: 100%; padding: 0 6px 0 12px; border: 0; background: transparent; color: var(--fg-2); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rv-recent:hover .rv-recent-go { color: var(--fg); }
.rv-recent-x { display: flex; align-items: center; justify-content: center; width: 24px; min-height: 24px; height: 100%; border: 0; background: transparent; color: var(--muted); flex: none; }
.rv-recent-x:hover { color: var(--danger); }

/* "This week" card (home/home.css styles it once the lazy chunk loads). Until then the pre-paint's
   data-home="on" keeps its last height reserved, so a returning visit never grows the page. */
.rv-home { width: min(680px, 96%); }
:root[data-home="on"] .rv-home[hidden] { display: block; visibility: hidden; height: var(--home-h); }
/* Wide screens (most Chromebooks): beside the column, top aligned with the greeting, so the card is
   seen without scrolling and takes no room from the tiles or Jump back in. */
@media (min-width: 1260px) {
	.rv-start-inner { position: relative; }
	.rv-home { position: absolute; top: 0; left: calc(100% + 20px); width: min(320px, calc((100vw - 100%) / 2 - 40px)); }
}

/* folder category chips + clear */
.rv-folder-clear { height: 32px; padding: 0 12px; border: 1px solid color-mix(in srgb, var(--danger) 30%, var(--line)); background: var(--bg); color: var(--danger); border-radius: var(--radius); font-size: 12px; flex: none; }
.rv-folder-clear:hover { background: var(--surface); }
.rv-folder-cats { display: flex; gap: 8px; flex-wrap: wrap; padding: 11px 24px; border-bottom: 1px solid var(--line); flex: none; }
.rv-chip { height: 28px; padding: 0 13px; border: 1px solid var(--line); background: var(--bg); color: var(--muted-2); border-radius: 14px; font-size: 12px; white-space: nowrap; }
.rv-chip:hover { border-color: var(--accent-2); color: var(--fg-2); }
.rv-chip.active { background: var(--accent); color: var(--on-accent); border-color: var(--accent); font-weight: 600; }
.rv-chip-group { display: flex; gap: 8px; flex-wrap: wrap; min-width: 0; }
.rv-folder-cats.rv-cats-books { justify-content: space-between; row-gap: 8px; }
.rv-chip-n { margin-left: 6px; opacity: .72; font-weight: 400; font-variant-numeric: tabular-nums; }
@media (max-width: 700px) {
	.rv-folder-cats.rv-cats-books { padding-left: 16px; padding-right: 16px; }
	.rv-folder-cats.rv-cats-books > .rv-chip-group:first-child { flex: 1 1 100%; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
	.rv-folder-cats.rv-cats-books > .rv-chip-group:first-child::-webkit-scrollbar { display: none; }
}

/* tile fallback for missing icons */
.rv-tile, .rv-tile-sm { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; }
.rv-tile { font-size: 18px; }
.rv-card-mono { position: absolute; inset: 0; display: flex; }
.rv-card-mono .rv-tile { font-size: 40px; }
.rv-card-mono .rv-card-img { position: static; width: 40px; height: 40px; margin: auto; padding: 0; }
.rv-tile-sm { font-size: 11px; }

/* card variants */
.rv-grid[data-style="app"] { grid-template-columns: repeat(auto-fill, minmax(116px, 1fr)); }
.rv-grid[data-style="tool"] { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.rv-grid[data-style="link"] { grid-template-columns: 1fr; gap: 8px; }
.rv-card-app { align-items: center; text-align: center; padding: 16px 8px 13px; gap: 10px; }
.rv-card-app .rv-card-title { padding: 0; white-space: normal; max-width: 100%; }
.rv-app-icon { width: 46px; height: 46px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius-lg); overflow: hidden; background: var(--surface-2); flex: none; }
.rv-app-icon img { width: 38px; height: 38px; object-fit: contain; }
.rv-card-tool { padding: 16px; gap: 9px; }
.rv-card-tool { position: relative; }
.rv-card-pin { position: absolute; top: 8px; right: 8px; width: 28px; height: 28px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--muted); display: flex; align-items: center; justify-content: center; }
.rv-card-pin:hover { background: var(--surface-2); color: var(--fg); }
.rv-card-pin[aria-pressed="true"] { color: var(--accent-ink); }
.rv-card-pin[aria-pressed="true"] svg { fill: currentColor; }
.rv-tool-icon { width: 32px; height: 32px; color: var(--accent-ink); }
.rv-tool-icon svg { width: 100%; height: 100%; }
.rv-card-tool .rv-card-title { padding: 0; font-weight: 600; color: var(--fg); white-space: normal; }
.rv-card-blurb { font-size: 12px; color: var(--muted); white-space: normal; line-height: 1.35; }
.rv-card-link { flex-direction: row; align-items: center; gap: 12px; padding: 9px 12px; }
.rv-card-link:hover { transform: none; }
.rv-link-fav { width: 26px; height: 26px; flex: none; border-radius: var(--radius-sm); overflow: hidden; display: flex; align-items: center; justify-content: center; background: var(--surface-2); }
.rv-link-fav img { width: 20px; height: 20px; }
.rv-link-text { flex: 1; min-width: 0; }
.rv-link-title { color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-link-url { color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-link-remove { width: 26px; height: 26px; border: 0; background: transparent; color: var(--muted); border-radius: var(--radius-sm); flex: none; display: flex; align-items: center; justify-content: center; }
.rv-link-remove:hover { background: var(--surface-2); color: var(--fg); }

/* command palette */
.rv-palette { position: fixed; inset: 0; z-index: 1000; background: rgba(0, 0, 0, 0.5); display: flex; align-items: flex-start; justify-content: center; padding-top: 12vh; }
.rv-palette-box { width: min(620px, 94%); background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); overflow: hidden; display: flex; flex-direction: column; max-height: 70vh; }
.rv-palette-input { height: 50px; border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--fg); font: inherit; font-size: 16px; padding: 0 18px; outline: none; user-select: text; -webkit-user-select: text; }
.rv-palette-list { overflow: auto; }
.rv-palette-item { display: flex; align-items: center; gap: 10px; padding: 10px 16px; cursor: pointer; }
.rv-palette-item.sel { background: var(--surface-2); }
.rv-palette-title { color: var(--fg); flex: none; max-width: 60%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-palette-sub { color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.rv-palette-kind { margin-left: auto; color: var(--muted-2); font-size: 11px; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 1px 6px; flex: none; }

/* find-in-page bar */
.rv-findbar { position: fixed; top: 8px; right: 16px; z-index: 1000; display: flex; align-items: center; gap: 4px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 5px 6px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); }
.rv-findbar input { height: 28px; width: 200px; border: 0; background: transparent; color: var(--fg); outline: none; font: inherit; padding: 0 6px; user-select: text; -webkit-user-select: text; }
.rv-find-btn { width: 28px; height: 28px; border: 0; background: transparent; color: var(--muted-2); border-radius: var(--radius-sm); }
.rv-find-btn:hover { background: var(--surface-2); color: var(--fg); }

/* favorite ★ on book + app cards */
.rv-card { position: relative; }
.rv-fav-star { position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; border: 0; border-radius: var(--radius); background: rgba(0, 0, 0, 0.55); color: #fff; opacity: 0.85; transition: opacity 0.12s ease, color 0.12s ease, background 0.12s ease; z-index: 2; }
.rv-fav-star svg { width: 16px; height: 16px; }
.rv-card:hover .rv-fav-star, .rv-card:focus-within .rv-fav-star, .rv-fav-star.on { opacity: 1; }
.rv-fav-star:hover { background: rgba(0, 0, 0, 0.7); }
.rv-fav-star.on { color: var(--accent-ink); }
.rv-fav-star.on svg path { fill: var(--accent); }
.rv-card-app .rv-fav-star { top: 5px; right: 5px; background: var(--surface-2); }
.rv-card-app .rv-fav-star:hover { background: var(--line); }

/* favorites: a small book cover thumb inside a link row */
.rv-link-cover { width: 42px; height: 30px; border-radius: var(--radius-sm); overflow: hidden; position: relative; background: linear-gradient(135deg, #1a1813, #0b0b0b); flex: none; }
.rv-link-cover .rv-card-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; padding: 0; }
.rv-link-cover .rv-card-fallback { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 9px; color: var(--muted-2); padding: 2px; text-align: center; }

/* pagination */
.rv-pager { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 10px 24px 14px; flex: none; border-top: 1px solid var(--line); }
.rv-pager-btn { height: 32px; padding: 0 14px; border: 1px solid var(--line); background: var(--surface); color: var(--fg); border-radius: var(--radius); font-size: 13px; }
.rv-pager-btn:hover:not([disabled]) { border-color: var(--accent-2); }
.rv-pager-btn[disabled] { opacity: 0.4; }
.rv-pager-ind { color: var(--muted); font-size: 12px; }

/* loading overlay + pipeline bar (covers the iframe white-flash) */
/* hidden (not just transparent) while off, so its Skip button is out of the Tab order and away
   from screen readers; visibility flips after the fade-out ends */
.rv-loader { position: absolute; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; background: var(--bg); opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.25s ease, visibility 0s linear 0.25s; }
.rv-loader[data-on="1"] { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity 0.25s ease 0.14s, visibility 0s linear 0s; } /* delayed fade-in → fast pages never flash it */
.rv-loader-card { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.rv-loader-row { display: flex; align-items: center; gap: 14px; }
.rv-loader-label { color: var(--muted-2); font-size: 13px; max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-loader-skip { height: 28px; padding: 0 13px; border: 1px solid var(--line); background: var(--surface); color: var(--fg-2); border-radius: var(--radius); font-size: 12px; }
.rv-loader-skip:hover { border-color: var(--accent-2); color: var(--fg); }
.rv-pipe { width: 260px; max-width: 70vw; height: 16px; border-radius: 999px; background: var(--surface-2); border: 1px solid var(--line); overflow: hidden; position: relative; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4); }
.rv-pipe span { position: absolute; top: 0; bottom: 0; left: -28px; right: -28px; background-image: radial-gradient(circle 4px at 14px 50%, var(--accent) 0 4px, transparent 5px); background-size: 28px 100%; background-repeat: repeat-x; animation: rvpipe 0.75s linear infinite; will-change: transform; }
@keyframes rvpipe { from { transform: translateX(0); } to { transform: translateX(28px); } }
@media (prefers-reduced-motion: reduce) { .rv-pipe span { animation-duration: 2.4s; } }
/* The loader is always in the DOM; don't keep animating it while it is hidden. */
.rv-loader[data-on="0"] .rv-pipe span { animation-play-state: paused; }

/* collapsible top chrome + pull tab */
.rv-root.collapsed .rv-tabstrip,
.rv-root.collapsed .rv-navbar,
.rv-root.collapsed .rv-bookmarksbar { display: none; }
.rv-pulltab { position: absolute; top: 0; left: 50%; transform: translateX(-50%); z-index: 60; display: flex; align-items: center; justify-content: center; width: 56px; height: 15px; padding: 0; border: 1px solid var(--line); border-top: 0; border-radius: 0 0 var(--radius) var(--radius); background: var(--surface); color: var(--muted-2); opacity: 0.75; transition: opacity 0.15s ease, height 0.15s ease, color 0.15s ease, background 0.15s ease; }
.rv-pulltab svg { width: 15px; height: 15px; }
.rv-pulltab:hover { opacity: 1; height: 20px; color: var(--fg); background: var(--surface-2); }

/* optional hiding of the top-left branding (Settings, Layout and start page) */
[data-brand="off"] .rv-brand #rv-logo,
[data-brand="off"] .rv-brand-name { display: none; }
[data-brand="off"] .rv-brand { display: none; }

/* font-preview dropdown: each option renders in its own face */
.rv-font-select option { font-size: 15px; padding: 3px 4px; }

/* off-screen image cards skip layout/paint (paginated grids stay light) */
.rv-grid[data-style="image"] .rv-card { content-visibility: auto; contain-intrinsic-size: auto 226px; }

/* tab context menu (right-click / long-press) */
.rv-ctxmenu { position: fixed; z-index: 200; min-width: 170px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 5px; box-shadow: 0 12px 36px rgba(0, 0, 0, 0.5); display: flex; flex-direction: column; }
.rv-ctxitem { display: flex; align-items: center; height: 30px; padding: 0 10px; border: 0; background: transparent; color: var(--fg-2); border-radius: var(--radius-sm); font-size: 13px; text-align: left; }
.rv-ctxitem:hover:not([disabled]) { background: var(--surface-2); color: var(--fg); }
.rv-ctxitem[disabled] { opacity: 0.4; }
.rv-ctxitem:focus-visible { background: var(--surface-2); color: var(--fg); outline-offset: -2px; }
.rv-ctxsep { height: 1px; background: var(--line); margin: 4px 6px; }

/* pinned tabs */
/* Pinned tabs sit in exactly the same cell as every other tab; losing the ✕ just
   frees the space up for the title. The 4px that used to be extra padding on the
   tab now lives on the title instead: horizontal padding is subtracted from a
   flex item's shrink base, so the wider padding made pinned tabs ~3px wider than
   their neighbours as soon as the strip was in the shrink range. */
.rv-tab.pinned { gap: 5px; }
.rv-tab.pinned .rv-tab-title { padding-right: 4px; }
.rv-tab-pin { display: flex; align-items: center; color: var(--accent-ink); flex: none; }

/* phone toolbar: extra buttons fold into a More tray (app/nav-more.js) */
.rv-more-btn { display: none; position: relative; }
.rv-nav-more { display: contents; }
.rv-more-dot::after { content: ""; position: absolute; top: 6px; right: 6px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
@media (max-width: 599px) {
	.rv-omnibox { min-width: 0; margin: 0 4px; }
	.rv-omnibox input { min-width: 0; width: 100%; }
	.rv-more-btn { display: flex; }
	.rv-nav-more { display: none; position: fixed; right: 8px; z-index: 315; gap: 2px; padding: 4px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35); }
	.rv-nav-more[data-open] { display: flex; }
	.rv-nav-more[data-open] { flex-wrap: wrap; max-width: calc(100vw - 16px); }
	.rv-nav-more .rv-extbar { flex: 1 0 100%; flex-direction: column; align-items: stretch; gap: 2px; padding-bottom: 4px; margin-bottom: 2px; border-bottom: 1px solid var(--line); }
	.rv-nav-more .rv-extbtn { width: auto; justify-content: flex-start; gap: 8px; padding: 0 10px; }
	.rv-nav-more .rv-extbtn-label { display: inline; font-size: 13px; color: var(--fg); }
	.rv-nav-more .rv-nav.rv-status { flex: 1 0 100%; justify-content: flex-start; gap: 8px; padding: 0 10px; }
	.rv-nav-more .rv-status .rv-status-text { display: inline; font-size: 13px; font-weight: 400; }
	/* two book covers per row instead of one giant one */
	.rv-grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; padding: 14px 16px 22px; }
}

/* Bigger hit targets whenever a touchscreen is present. A convertible Chromebook in laptop mode
   reports pointer: fine, so this must ask about any pointer. */
@media (any-pointer: coarse) {
	.rv-nav, .rv-newtab { width: 40px; height: 40px; }
	.rv-tab-close { width: 26px; height: 26px; }
	.rv-shortcut-btn { width: 72px; height: 72px; }
}

/* Reserve the start-screen shortcut grid's wrapped height per width band so the
   grid - and the ad below it - don't shift down when the dashboard hydrates after
   first paint. A container pinned at min-height stays put when its content fits. */
@media (max-width: 399px) { .rv-shortcuts { min-height: 318px; } } /* 3 rows (incl. 360px) */
@media (min-width: 400px) and (max-width: 665px) { .rv-shortcuts { min-height: 206px; } } /* 2 rows */
/* Fixed-width columns, so every column lines up whatever the label lengths or font. On a
   laptop all 14 shortcuts plus All shortcuts fit in two rows of 8. */
.rv-shortcuts, :root[data-theme="bedazzled"] .rv-shortcuts { display: grid; grid-template-columns: repeat(auto-fill, 96px); justify-content: center; justify-items: center; gap: 20px 4px; width: 100%; }
.rv-shortcut span { text-align: center; }
@media (min-width: 666px) {
	.rv-shortcuts, :root[data-theme="bedazzled"] .rv-shortcuts { grid-template-columns: repeat(auto-fill, 88px); gap: 20px 2px; }
}

/* address-bar / search autocomplete dropdown */
.rv-suggest { position: fixed; z-index: 300; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 5px; box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5); max-height: 52vh; overflow-y: auto; }
.rv-suggest-item { display: flex; align-items: center; gap: 10px; height: 34px; padding: 0 10px; border-radius: var(--radius); cursor: pointer; color: var(--fg-2); font-size: 13px; }
.rv-suggest-item.sel { background: var(--surface-2); color: var(--fg); }
.rv-suggest-ic { display: flex; flex: none; width: 16px; height: 16px; color: var(--muted-2); }
.rv-suggest-ic svg { width: 16px; height: 16px; }
.rv-suggest-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-suggest-label b { color: var(--fg); font-weight: 600; }
.rv-suggest-sub { flex: none; color: var(--muted-2); font-size: 11px; margin-left: 8px; max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* boot-failure recovery screen */
.rv-fatal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; background: var(--bg); padding: 24px; }
.rv-fatal-card { display: flex; flex-direction: column; align-items: center; gap: 13px; text-align: center; max-width: 390px; }
.rv-fatal-card svg { width: 48px; height: 48px; color: var(--accent-ink); }
.rv-fatal-card h1 { color: var(--fg); font-size: 20px; }
.rv-fatal-card p { color: var(--muted-2); font-size: 14px; line-height: 1.5; }
.rv-fatal-actions { display: flex; gap: 10px; margin-top: 4px; flex-wrap: wrap; justify-content: center; }

/* --- auto-update toast (app/update.js) ----------------------------------- */
.rv-update { position: fixed; left: 50%; bottom: 18px; transform: translate(-50%, 14px); z-index: 10000; display: flex; align-items: center; gap: 10px; max-width: calc(100vw - 28px); padding: 9px 9px 9px 15px; background: var(--surface); color: var(--fg); border: 1px solid var(--line); border-radius: var(--radius-lg); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45); font-size: var(--fs); opacity: 0; pointer-events: none; transition: opacity 0.22s ease, transform 0.22s ease; }
.rv-update.rv-update-in { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.rv-update-msg { color: var(--fg); }
.rv-update-reload { height: 30px; padding: 0 14px; border: 1px solid var(--accent); border-radius: var(--radius); background: var(--accent); color: var(--on-accent); font: inherit; font-weight: 600; cursor: pointer; flex: none; }
.rv-update-reload:hover { filter: brightness(1.06); }
.rv-update-x { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: 0; border-radius: var(--radius); background: transparent; color: var(--muted); cursor: pointer; flex: none; font-size: 12px; }
.rv-update-x:hover { color: var(--fg); background: var(--line); }

/* --- bell reminder toast (app/bell.js) - reuses the .rv-update surface ---- */
.rv-bell .rv-bell-ic { display: flex; align-items: center; justify-content: center; flex: none; color: var(--accent-ink); }
.rv-bell .rv-bell-ic svg { width: 20px; height: 20px; }
.rv-bell-msg { color: var(--fg); font-weight: 500; }

/* --- next-bell line on the start screen (app/bell.js) -------------------- */
.rv-nextbell { margin-top: -2px; font-size: 13px; color: var(--muted-2); display: inline-flex; align-items: center; gap: 6px; padding: 4px 12px; border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--surface); }
:root[data-wallpaper="on"] .rv-nextbell { background: color-mix(in srgb, var(--surface) 55%, transparent); }
/* --- "What's new" chip after an update (app/whats-new.js) and the install note (app/install.js) --- */
.rv-news { display: inline-flex; align-items: center; gap: 2px; max-width: 100%; padding: 2px; border: 1px solid var(--line); border-radius: var(--radius-pill); background: var(--surface); }
.rv-news[hidden] { display: none; }
:root[data-wallpaper="on"] .rv-news { background: color-mix(in srgb, var(--surface) 70%, transparent); }
/* Fixed line heights: the chip is drawn before the web font arrives, and with "normal" a long label
   that wraps on a phone grew a few px on the swap and pushed the search box and shortcuts down. */
.rv-news-go { display: inline-flex; align-items: center; gap: 8px; min-height: 32px; min-width: 0; padding: 2px 10px 2px 4px; border: 0; border-radius: var(--radius-pill); background: none; color: var(--fg); font: inherit; font-size: 13px; line-height: 17px; text-align: left; cursor: pointer; }
.rv-news-go:hover { background: var(--surface-2); }
.rv-news-tag { flex: none; padding: 1px 8px; border-radius: var(--radius-pill); background: var(--accent); color: var(--on-accent); font-size: 11px; line-height: 14px; font-weight: 700; letter-spacing: .3px; }
.rv-news-x { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%; background: none; color: var(--muted-2); cursor: pointer; }
.rv-news-x:hover { background: var(--surface-2); color: var(--fg); }
.rv-news-x svg, .rv-install-x svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.rv-install { left: 16px; transform: translateY(14px); align-items: flex-start; flex-wrap: wrap; gap: 8px 12px; width: min(380px, calc(100vw - 32px)); padding: 12px 10px 12px 14px; }
.rv-install.rv-update-in { transform: none; }
.rv-install-txt { flex: 1 1 200px; min-width: 0; }
.rv-install-h { display: block; margin: 0 0 2px; font-size: 14px; font-weight: 600; color: var(--fg); }
.rv-install-p { margin: 0; font-size: 13px; color: var(--muted-2); line-height: 1.4; }
.rv-install-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; flex-basis: 100%; }
.rv-install-no { min-height: 30px; padding: 0 10px; border: 1px solid var(--line); border-radius: var(--radius); background: transparent; color: var(--fg); font: inherit; font-size: 13px; cursor: pointer; }
.rv-install-no:hover { background: var(--surface-2); }
.rv-install-off { min-height: 24px; margin-left: auto; padding: 0 2px; border: 0; background: none; color: var(--muted-2); font: inherit; font-size: 12px; text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }
.rv-install-x { position: absolute; top: 6px; right: 6px; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 0; border-radius: var(--radius); background: none; color: var(--muted); cursor: pointer; }
.rv-install-x:hover { background: var(--line); color: var(--fg); }
@media (prefers-reduced-motion: reduce) { .rv-install, .rv-install.rv-update-in { transform: none; transition: opacity .12s linear; } }
.rv-offline { display: none; margin: 0; font-size: 14px; color: var(--fg-2); text-align: center; }
:root[data-offline] .rv-offline { display: block; }
:root[data-offline] :is(.rv-startsearch, .rv-recents, .rv-studying, .rv-shortcut[data-net], [class*="rv-slot-start"]) { display: none; }
.rv-studying { flex: none; margin: 0; font-size: 13px; color: var(--muted-2); text-align: center; animation: rv-studying-in 0.6s ease-out; }
@keyframes rv-studying-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .rv-studying { animation: none; } }
:root[data-animations="off"] .rv-studying { animation: none; }
:root[data-wallpaper="on"] .rv-studying { color: var(--fg-2); padding: 4px 12px; border-radius: var(--radius-pill); background: var(--veil); -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px); } /* on the photo itself, so a veil like the search box */

/* --- background-music player (app/music.js) ----------------------------- */
.rv-music { position: fixed; left: 16px; bottom: 16px; z-index: 9000; display: flex; align-items: center; gap: 6px; max-width: min(340px, calc(100vw - 28px)); padding: 6px 10px 6px 8px; background: var(--surface); color: var(--fg); border: 1px solid var(--line); border-radius: var(--radius-pill); box-shadow: 0 8px 26px rgba(0, 0, 0, 0.4); font-size: 13px; }
.rv-music[hidden] { display: none; }
.rv-music-ic { display: flex; align-items: center; justify-content: center; flex: none; color: var(--accent-ink); }
.rv-music-ic svg { width: 18px; height: 18px; }
.rv-music-btn { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; flex: none; border: 0; border-radius: 50%; background: transparent; color: var(--fg); cursor: pointer; }
.rv-music-btn svg { width: 18px; height: 18px; }
.rv-music-btn:hover { background: var(--line); }
.rv-music-btn[hidden] { display: none; }
.rv-music-play { color: var(--on-accent); background: var(--accent); }
.rv-music-play:hover { background: var(--accent); filter: brightness(1.06); }
.rv-music-label { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg-2); padding: 0 2px; }
.rv-music-vol { flex: none; width: 74px; accent-color: var(--accent); cursor: pointer; }
@media (max-width: 560px) { .rv-music-vol { width: 52px; } .rv-music { max-width: calc(100vw - 24px); } }

/* --- wallpaper (app/wallpaper.js) ---------------------------------------- */
/* A single fixed layer behind .rv-root. The image paints on ::before (blurred in
   isolation, over-sized so the blur never reveals a hard edge); the dim scrim is
   ::after. html keeps an opaque --bg so a contained/tiled image never flashes the
   white canvas. Surfaces are turned transparent below so the layer shows through. */
.rv-wallpaper { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
/* Fully hidden unless a wallpaper is active. Without this, after switching to None
   or resetting, the layer's leftover dim scrim would paint over the shell (the
   chrome loses its z-index lift), tinting the top bar. */
:root:not([data-wallpaper="on"]) .rv-wallpaper { display: none; }
.rv-wallpaper::before {
	content: ""; position: absolute;
	inset: calc(-2 * var(--wp-blur, 0px) - 8px);
	background-color: var(--wp-bg, transparent);
	background-image: var(--wp-image, none);
	background-size: var(--wp-size, cover);
	background-position: center;
	background-repeat: var(--wp-repeat, no-repeat);
	filter: blur(var(--wp-blur, 0px));
}
.rv-wallpaper::after { content: ""; position: absolute; inset: 0; background: rgba(0, 0, 0, var(--wp-dim, 0)); }

/* Reveal the layer: lift the shell into its own stacking context above the layer
   and clear the backgrounds along the start-screen path. Chrome + proxied frames
   stay opaque, so only the new-tab screen shows the wallpaper in "start" scope. */
:root[data-wallpaper="on"] .rv-root { position: relative; z-index: 1; background: transparent; }
:root[data-wallpaper="on"] .rv-content,
:root[data-wallpaper="on"] .rv-start { background: transparent; }
:root[data-wallpaper="on"] .rv-greeting,
:root[data-wallpaper="on"] .rv-clock,
:root[data-wallpaper="on"] .rv-date,
:root[data-wallpaper="on"] .rv-studying,
:root[data-wallpaper="on"] .rv-shortcut span { text-shadow: 0 1px 16px rgba(0, 0, 0, 0.55); }
/* light theme over a (usually dark) wallpaper: the text is dark, so flip the halo
   to a light glow instead of a dark one */
:root[data-mode="light"][data-wallpaper="on"] .rv-greeting,
:root[data-mode="light"][data-wallpaper="on"] .rv-clock,
:root[data-mode="light"][data-wallpaper="on"] .rv-date,
:root[data-mode="light"][data-wallpaper="on"] .rv-studying,
:root[data-mode="light"][data-wallpaper="on"] .rv-shortcut span { text-shadow: 0 1px 16px rgba(255, 255, 255, 0.7); }
:root[data-wallpaper="on"] .rv-startsearch, :root[data-wallpaper="on"] .rv-shortcut-btn, :root[data-wallpaper="on"] .rv-recent { background: var(--veil); -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px); }

/* "app" scope: the wallpaper sits behind the whole shell, so the chrome + folder
   views go translucent too. Proxied page iframes (.rv-frame) deliberately stay
   opaque - a website must never bleed the wallpaper through its own page. */
:root[data-wallpaper="on"][data-wp-scope="app"] .rv-tabstrip,
:root[data-wallpaper="on"][data-wp-scope="app"] .rv-navbar,
:root[data-wallpaper="on"][data-wp-scope="app"] .rv-bookmarksbar,
:root[data-wallpaper="on"][data-wp-scope="app"] .rv-folder-head,
:root[data-wallpaper="on"][data-wp-scope="app"] .rv-folder-cats,
:root[data-wallpaper="on"][data-wp-scope="app"] .rv-pager { background: var(--veil); -webkit-backdrop-filter: blur(7px); backdrop-filter: blur(7px); }
:root[data-wallpaper="on"][data-wp-scope="app"] .rv-folder { background: transparent; }

/* === Frutiger Aero - glossy aqua-glass skin (scoped) ======================= */
/* Every rule is scoped to [data-theme="frutiger"], so no other theme is touched.
   Decorative only: a sky→meadow backdrop, glossy "gel" surfaces, frosted glass
   start controls, and the signature aqua gel button. Proxied page iframes
   (.rv-frame) are deliberately never styled. */

/* Sky-to-meadow backdrop (suppressed when a wallpaper owns the background). */
:root[data-theme="frutiger"]:not([data-wallpaper="on"]) .rv-root {
	background-color: #bfe6ff;
	background-image: var(--look-backdrop);
	background-attachment: fixed;
}
:root[data-theme="frutiger"]:not([data-wallpaper="on"]) .rv-content, :root[data-theme="frutiger"]:not([data-wallpaper="on"]) .rv-start, :root[data-theme="frutiger"]:not([data-wallpaper="on"]) .rv-folder { background: transparent; }

/* Glossy "gel" surfaces: a white sheen up top fading to a faint aqua, a bright
   inner highlight line, and a soft drop shadow - the signature Aero look. */
:root[data-theme="frutiger"] .rv-omnibox,
:root[data-theme="frutiger"] .rv-card,
:root[data-theme="frutiger"] .rv-btn,
:root[data-theme="frutiger"] .rv-recent,
:root[data-theme="frutiger"] .rv-palette-box,
:root[data-theme="frutiger"] .rv-suggest,
:root[data-theme="frutiger"] .rv-ctxmenu,
:root[data-theme="frutiger"] .rv-update,
:root[data-theme="frutiger"] .rv-music,
:root[data-theme="frutiger"] .rv-findbar,
:root[data-theme="frutiger"] .rv-err-icon {
	background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0.4) 50%, rgba(170, 214, 240, 0.28));
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 1px 3px rgba(20, 70, 100, 0.16);
}

/* Glassy top chrome with a faint sheen. */
:root[data-theme="frutiger"] .rv-tabstrip, :root[data-theme="frutiger"] .rv-navbar, :root[data-theme="frutiger"] .rv-bookmarksbar {
	background-image: linear-gradient(180deg, #ffffff, #d7ecfb);
}
/* Active tab pops as a glossy white chip. */
:root[data-theme="frutiger"] .rv-tab.active {
	background-image: linear-gradient(180deg, #ffffff, #e9f6ff);
	box-shadow: inset 0 1px 0 #fff;
}

/* Frosted-glass start-screen controls - they read as glass even with no wallpaper. */
:root[data-theme="frutiger"] .rv-startsearch,
:root[data-theme="frutiger"] .rv-shortcut-btn {
	background-color: rgba(255, 255, 255, 0.62);
	background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(206, 236, 255, 0.55));
	-webkit-backdrop-filter: blur(7px);
	backdrop-filter: blur(7px);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 2px 6px rgba(20, 70, 100, 0.16);
}

/* The iconic glossy aqua gel button. Fixed colors (independent of --accent) so it
   stays Frutiger even if the user picks a different accent. Defined LAST so it
   wins over the generic .rv-btn gel above. */
:root[data-theme="frutiger"] .rv-btn-primary,
:root[data-theme="frutiger"] .rv-tbtn-accent,
:root[data-theme="frutiger"] .rv-update-reload,
:root[data-theme="frutiger"] .rv-chip.active {
	background-image: linear-gradient(180deg, #8fe6f2 0%, #2cc0d6 48%, #18a6c2 50%, #45cee0 100%);
	border-color: #1391aa;
	color: #053039;
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85), 0 1px 4px rgba(19, 145, 170, 0.38);
}
:root[data-theme="frutiger"] .rv-btn-primary:hover,
:root[data-theme="frutiger"] .rv-update-reload:hover { filter: brightness(1.05); }

/* === Frutiger Aero Dark - deep "Aero glass" skin (scoped) ================== */
:root[data-theme="frutiger-dark"]:not([data-wallpaper="on"]) .rv-root {
	background-color: #07151c;
	background-image: var(--look-backdrop);
	background-attachment: fixed;
}
:root[data-theme="frutiger-dark"]:not([data-wallpaper="on"]) .rv-content,
:root[data-theme="frutiger-dark"]:not([data-wallpaper="on"]) .rv-folder { background: transparent; }
/* aqua aurora glow over the start screen */
:root[data-theme="frutiger-dark"]:not([data-wallpaper="on"]) .rv-start { background: transparent; }
/* dark glossy gel surfaces: a faint top sheen over the dark surface */
:root[data-theme="frutiger-dark"] .rv-omnibox,
:root[data-theme="frutiger-dark"] .rv-card,
:root[data-theme="frutiger-dark"] .rv-btn,
:root[data-theme="frutiger-dark"] .rv-recent,
:root[data-theme="frutiger-dark"] .rv-palette-box,
:root[data-theme="frutiger-dark"] .rv-suggest,
:root[data-theme="frutiger-dark"] .rv-ctxmenu,
:root[data-theme="frutiger-dark"] .rv-update,
:root[data-theme="frutiger-dark"] .rv-music,
:root[data-theme="frutiger-dark"] .rv-findbar,
:root[data-theme="frutiger-dark"] .rv-err-icon {
	background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.02) 50%, rgba(34, 211, 238, 0.05));
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 1px 3px rgba(0, 0, 0, 0.45);
}
/* glassy top chrome */
:root[data-theme="frutiger-dark"] .rv-tabstrip, :root[data-theme="frutiger-dark"] .rv-navbar, :root[data-theme="frutiger-dark"] .rv-bookmarksbar {
	background-color: #0b212a;
	background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.06), rgba(255, 255, 255, 0.01));
}
:root[data-theme="frutiger-dark"] .rv-tab.active {
	background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.03));
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
}
/* frosted start controls */
:root[data-theme="frutiger-dark"] .rv-startsearch,
:root[data-theme="frutiger-dark"] .rv-shortcut-btn {
	background-color: rgba(14, 39, 49, 0.55);
	background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(34, 211, 238, 0.05));
	-webkit-backdrop-filter: blur(7px);
	backdrop-filter: blur(7px);
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 2px 8px rgba(0, 0, 0, 0.4);
}
/* aqua gel button (fixed colors, accent-independent) */
:root[data-theme="frutiger-dark"] .rv-btn-primary,
:root[data-theme="frutiger-dark"] .rv-tbtn-accent,
:root[data-theme="frutiger-dark"] .rv-update-reload,
:root[data-theme="frutiger-dark"] .rv-chip.active {
	background-image: linear-gradient(180deg, #6fe3f2 0%, #22b8d4 48%, #149fbe 50%, #38c9de 100%);
	border-color: #128ba3;
	color: #04232b;
	box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 1px 4px rgba(0, 0, 0, 0.4);
}
:root[data-theme="frutiger-dark"] .rv-btn-primary:hover,
:root[data-theme="frutiger-dark"] .rv-update-reload:hover { filter: brightness(1.06); }

/* === Bedazzled Vault: black and gold, lit like a desk lamp ================= */
/* the warm backdrop and its glow come from --look-backdrop; a faint grain stops banding */
:root[data-theme="bedazzled"]:not([data-wallpaper="on"]) .rv-root {
	background-color: var(--bg);
	background-image: url(/looks/grain-soft.svg), var(--look-backdrop);
	background-attachment: fixed;
}
:root[data-theme="bedazzled"]:not([data-wallpaper="on"]) .rv-content, :root[data-theme="bedazzled"]:not([data-wallpaper="on"]) .rv-start, :root[data-theme="bedazzled"]:not([data-wallpaper="on"]) .rv-folder { background: transparent; }
/* matte surfaces with a whisper of warmth at the top edge */
:root[data-theme="bedazzled"] .rv-omnibox,
:root[data-theme="bedazzled"] .rv-card,
:root[data-theme="bedazzled"] .rv-btn,
:root[data-theme="bedazzled"] .rv-recent,
:root[data-theme="bedazzled"] .rv-palette-box,
:root[data-theme="bedazzled"] .rv-suggest,
:root[data-theme="bedazzled"] .rv-ctxmenu,
:root[data-theme="bedazzled"] .rv-update,
:root[data-theme="bedazzled"] .rv-music,
:root[data-theme="bedazzled"] .rv-findbar,
:root[data-theme="bedazzled"] .rv-err-icon {
	background-image: linear-gradient(180deg, rgba(255, 236, 200, 0.035), rgba(255, 236, 200, 0) 60%);
	box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
}
:root[data-theme="bedazzled"] .rv-tabstrip, :root[data-theme="bedazzled"] .rv-navbar, :root[data-theme="bedazzled"] .rv-bookmarksbar { background-color: #130f0a; }
:root[data-theme="bedazzled"] .rv-tab.active { background-image: linear-gradient(180deg, rgba(255, 236, 200, 0.06), rgba(233, 196, 106, 0.02)); }
:root[data-theme="bedazzled"] .rv-startsearch,
:root[data-theme="bedazzled"] .rv-shortcut-btn {
	background-color: rgba(26, 20, 12, 0.6);
	-webkit-backdrop-filter: blur(6px);
	backdrop-filter: blur(6px);
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
:root[data-theme="bedazzled"] .rv-startsearch { border-color: var(--line-strong); }
/* satin gold for the one main action on screen (fixed colors, whatever the accent) */
:root[data-theme="bedazzled"] .rv-btn-primary,
:root[data-theme="bedazzled"] .rv-tbtn-accent,
:root[data-theme="bedazzled"] .rv-update-reload,
:root[data-theme="bedazzled"] .rv-chip.active {
	background-image: linear-gradient(180deg, #f1d48a, #dcb35a);
	border-color: #b58a2e;
	color: var(--on-accent);
	box-shadow: inset 0 1px 0 rgba(255, 250, 230, 0.45);
}
:root[data-theme="bedazzled"] .rv-btn-primary:hover, :root[data-theme="bedazzled"] .rv-tbtn-accent:hover, :root[data-theme="bedazzled"] .rv-update-reload:hover { filter: brightness(1.05); }
:root[data-theme="bedazzled"] .rv-clock { font-size: clamp(40px, 6vw, 52px); font-weight: 300; }

/* === Zen and Zen Paper: ink, washi paper, one ensō and one seal ============ */
:root[data-theme^="zen"] { --zen-grain: url(/looks/grain-ink.svg); }
:root[data-theme="zen-paper"] { --zen-grain: url(/looks/grain-paper.svg); }
:root[data-theme^="zen"]:not([data-wallpaper="on"]) .rv-root {
	background-color: var(--bg);
	background-image: var(--zen-grain), var(--look-backdrop);
	background-attachment: fixed;
}
:root[data-theme^="zen"]:not([data-wallpaper="on"]) .rv-content, :root[data-theme^="zen"]:not([data-wallpaper="on"]) .rv-start, :root[data-theme^="zen"]:not([data-wallpaper="on"]) .rv-folder { background: transparent; }
/* === Spooky: the moonlit plum night and pumpkin glow from --look-backdrop ===== */
:root[data-theme="spooky"]:not([data-wallpaper="on"]) .rv-root {
	background-color: var(--bg);
	background-image: var(--look-backdrop);
	background-attachment: fixed;
}
:root[data-theme="spooky"]:not([data-wallpaper="on"]) .rv-content, :root[data-theme="spooky"]:not([data-wallpaper="on"]) .rv-start, :root[data-theme="spooky"]:not([data-wallpaper="on"]) .rv-folder { background: transparent; }
:root[data-theme^="zen"] .rv-omnibox,
:root[data-theme^="zen"] .rv-card,
:root[data-theme^="zen"] .rv-recent,
:root[data-theme^="zen"] .rv-palette-box,
:root[data-theme^="zen"] .rv-suggest,
:root[data-theme^="zen"] .rv-ctxmenu,
:root[data-theme^="zen"] .rv-music { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); }
:root[data-theme="zen-paper"] .rv-card,
:root[data-theme="zen-paper"] .rv-recent { box-shadow: 0 1px 2px rgba(60, 40, 20, 0.08); }
:root[data-theme^="zen"] .rv-tabstrip, :root[data-theme^="zen"] .rv-navbar, :root[data-theme^="zen"] .rv-bookmarksbar { background-color: var(--surface); }
:root[data-theme^="zen"] .rv-tab.active { background: linear-gradient(var(--accent), var(--accent)) 50% 0 / calc(100% - 24px) 2px no-repeat, var(--bg); }
:root[data-theme^="zen"] .rv-startsearch { background: var(--surface); border-color: var(--line-strong); }
:root[data-theme^="zen"] .rv-shortcut-btn { background: var(--surface); }
:root[data-theme^="zen"] .rv-clock { font-family: var(--font-display); font-weight: 500; font-size: clamp(42px, 6vw, 54px); letter-spacing: 0.02em; font-variant-numeric: lining-nums tabular-nums; }
:root[data-theme^="zen"] .rv-greeting { font-family: var(--font-display); font-size: 16px; letter-spacing: 0.04em; }
:root[data-theme^="zen"] .rv-date { letter-spacing: 0.14em; text-transform: uppercase; font-size: 11.5px; font-weight: 600; }
/* the ensō sits behind the clock; the seal is pressed in the open gap where the brush lifted,
   the way a painter stamps beside the end of the stroke */
:root[data-theme^="zen"] .rv-start-inner { position: relative; isolation: isolate; --enso: min(300px, 64vw); }
:root[data-theme^="zen"]:not([data-wallpaper="on"]) .rv-start-inner::before,
:root[data-theme^="zen"]:not([data-wallpaper="on"]) .rv-start-inner::after { content: ""; position: absolute; left: 50%; z-index: -1; pointer-events: none; }
:root[data-theme^="zen"]:not([data-wallpaper="on"]) .rv-start-inner::before {
	top: calc(64px - var(--enso) / 2);
	width: var(--enso);
	height: var(--enso);
	margin-left: calc(var(--enso) / -2);
	background: var(--fg);
	-webkit-mask: url(/looks/enso.svg) center / contain no-repeat;
	mask: url(/looks/enso.svg) center / contain no-repeat;
	opacity: 0.07;
	animation: rv-zen-breathe 12s ease-in-out infinite;
}
:root[data-theme^="zen"]:not([data-wallpaper="on"]) .rv-start-inner::after {
	--seal-w: calc(var(--enso) * 0.064);
	top: calc(64px - var(--enso) * 0.37 - var(--seal-w) * 0.6);
	margin-left: calc(var(--enso) * 0.21 - var(--seal-w) / 2);
	width: var(--seal-w);
	height: calc(var(--seal-w) * 1.2);
	background: var(--accent);
	-webkit-mask: url(/looks/seal.svg) center / contain no-repeat;
	mask: url(/looks/seal.svg) center / contain no-repeat;
	transform: rotate(-4deg);
	opacity: 0.82;
}
:root[data-theme="zen-paper"]:not([data-wallpaper="on"]) .rv-start-inner::before { opacity: 0.09; }
@keyframes rv-zen-breathe { 0%, 100% { opacity: 0.06; } 50% { opacity: 0.09; } }
@media (max-height: 420px) { :root[data-theme^="zen"] .rv-start-inner::before, :root[data-theme^="zen"] .rv-start-inner::after { display: none; } }
@media (prefers-reduced-motion: reduce) { :root[data-theme^="zen"] .rv-start-inner::before { animation: none !important; } }
:root[data-perf="on"] .rv-start-inner::before,
:root[data-animations="off"] .rv-start-inner::before { animation: none !important; }
:root[data-perf="on"][data-theme^="zen"] .rv-root,
:root[data-perf="on"][data-theme="bedazzled"] .rv-root { background-image: var(--look-backdrop); }
:root[data-theme^="zen"] .rv-page-title::after { content: ""; display: inline-block; width: 9px; height: 11px; margin-left: 10px; background: var(--accent); -webkit-mask: url(/looks/seal.svg) center / contain no-repeat; mask: url(/looks/seal.svg) center / contain no-repeat; transform: rotate(-3.5deg); vertical-align: 0; opacity: 0.85; }
:root[data-theme^="zen"] .rv-btn-primary:hover,
:root[data-theme^="zen"] .rv-tbtn-accent:hover { background: var(--accent); filter: brightness(1.08); }

/* Content pages (Settings, Tools, Help, Status, Study Hall, 404; <html class="rv-shell">) sit on
   the same backdrop as the start page: the page carries it and the body stays clear */
:root.rv-shell { background-color: var(--bg); background-image: var(--look-backdrop); background-attachment: fixed; }
:root.rv-shell[data-theme^="zen"]:not([data-perf="on"]) { background-image: var(--zen-grain), var(--look-backdrop); }
:root.rv-shell > body { background: transparent; }
.rv-prose h1, .rv-prose h2, .rv-tool-title, .rv-forum-title, .rv-lb-title, .rv-quests-title, .rv-folder-title { font-family: var(--font-display); }
:root[data-theme^="zen"] .rv-group, :root[data-theme^="zen"] .rv-section-title, :root[data-theme^="zen"] .rv-extp-cat { letter-spacing: 0.14em; }

/* --- "Jump back in" row (start screen): books, tools, a deck, open tasks -- */
.rv-jumpback { display: flex; flex-direction: column; gap: 10px; width: min(680px, 96%); }
.rv-jumpback-head { font-size: 13px; line-height: 16px; height: 16px; color: var(--muted-2); font-weight: 600; padding-left: 2px; }
.rv-jumpback-row { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 6px; scrollbar-width: thin; }
.rv-jumpback-row::-webkit-scrollbar { height: 6px; }
.rv-jumpback-item { position: relative; flex: none; width: 92px; }
.rv-jumpback-card { display: flex; flex-direction: column; gap: 6px; width: 92px; border: 0; background: transparent; padding: 0; text-align: left; }
.rv-jumpback-cover { width: 92px; height: 92px; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); background: linear-gradient(135deg, #1a1813, #0b0b0b); display: flex; align-items: center; justify-content: center; color: #cfc8b8; font-weight: 700; font-size: 22px; } /* light text: the cover is always dark */
.rv-jumpback-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rv-jumpback-card:hover .rv-jumpback-cover { border-color: var(--accent-2); }
.rv-jumpback-name { font-size: 11px; color: var(--fg-2); line-height: 14px; height: 28px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.rv-jumpback-x { position: absolute; top: 2px; right: 2px; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; border: 0; border-radius: 50%; background: rgba(0, 0, 0, 0.55); color: #fff; opacity: 0; pointer-events: none; transition: opacity 0.12s ease; }
.rv-jumpback-item:hover .rv-jumpback-x, .rv-jumpback-item:focus-within .rv-jumpback-x { opacity: 1; pointer-events: auto; }
.rv-jumpback-x:hover { background: rgba(0, 0, 0, 0.78); color: var(--danger); }
:root[data-wallpaper="on"] .rv-jumpback-cover { background: var(--veil); }
:root .rv-jumpback-cover.rv-jumpback-chip { background: color-mix(in srgb, var(--accent) 10%, var(--surface)); color: var(--accent-ink); }
.rv-jumpback-chip svg { width: 38px; height: 38px; }
.rv-jumpback-n { font-size: 34px; font-weight: 800; font-variant-numeric: tabular-nums; }
.rv-jumpback-x:focus-visible { opacity: 1; }
@media (hover: none), (any-pointer: coarse) { .rv-jumpback-x { opacity: 0.85; pointer-events: auto; } }

[hidden] { display: none !important; }

/* --- Community forums -------------------------------------------------------
   Built entirely from the theme tokens (--surface, --accent, --line, --fg ...),
   so a Look preset / custom theme restyles the forum with everything else - there
   is no second palette here. The forums view sets the grid container's data-style
   to "forum", which switches it out of grid layout into a single readable column. */
.rv-grid[data-style="forum"] { display: block; max-width: 820px; margin: 0 auto; width: 100%; }
.rv-forum { display: flex; flex-direction: column; gap: 14px; }
.rv-forum-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.rv-forum-title { font-size: 22px; font-weight: 700; color: var(--fg); margin: 0; letter-spacing: 0.2px; }
.rv-forum-title:focus { outline: none; }
.rv-forum-sub { color: var(--muted); font-size: 14px; margin: -6px 0 4px; line-height: 1.5; }
.rv-forum-back { background: transparent; border: 1px solid var(--line); color: var(--fg-2); font-size: 13px; font-weight: 600; padding: 6px 12px; border-radius: var(--radius-pill); cursor: pointer; transition: border-color 0.12s, color 0.12s; }
.rv-forum-back:hover { border-color: var(--accent-2); color: var(--fg); }
.rv-forum-loading, .rv-forum-empty { color: var(--muted); font-size: 14px; padding: 18px 4px; text-align: center; }

/* category list */
.rv-forum-cats { display: flex; flex-direction: column; gap: 10px; }
.rv-forum-cat { display: flex; align-items: center; justify-content: space-between; gap: 14px; text-align: left; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; cursor: pointer; transition: border-color 0.12s, transform 0.12s, background 0.12s; }
.rv-forum-cat:hover { border-color: var(--accent-2); transform: translateY(-1px); }
.rv-forum-cat-name { font-size: 16px; font-weight: 600; color: var(--fg); }
.rv-forum-cat-blurb { font-size: 13px; color: var(--muted); margin-top: 2px; }
.rv-forum-cat-count { flex: none; min-width: 40px; text-align: center; font-size: 15px; font-weight: 700; color: var(--accent-ink); background: var(--surface-2); border-radius: var(--radius-sm); padding: 6px 10px; }

/* actions + new-thread */
.rv-forum-actions { display: flex; gap: 10px; }
.rv-forum-new { background: var(--accent); color: var(--on-accent); border: 1px solid var(--accent-2); font-size: 14px; font-weight: 600; padding: 9px 18px; border-radius: var(--radius-sm); cursor: pointer; transition: filter 0.12s; }
.rv-forum-new:hover { filter: brightness(1.08); }
.rv-forum-new:disabled { opacity: 0.6; cursor: default; }
.rv-forum-cancel { background: transparent; color: var(--fg-2); border: 1px solid var(--line); font-size: 14px; font-weight: 600; padding: 9px 18px; border-radius: var(--radius-sm); cursor: pointer; }
.rv-forum-cancel:hover { border-color: var(--accent-2); color: var(--fg); }

/* thread list */
.rv-forum-threads { display: flex; flex-direction: column; gap: 8px; }
.rv-forum-thread { display: flex; align-items: center; justify-content: space-between; gap: 14px; text-align: left; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 13px 16px; cursor: pointer; transition: border-color 0.12s, background 0.12s; }
.rv-forum-thread:hover { border-color: var(--accent-2); }
.rv-forum-thread-title { font-size: 15px; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: 8px; }
.rv-forum-thread-meta { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.rv-forum-thread-count { flex: none; min-width: 34px; text-align: center; font-size: 13px; font-weight: 700; color: var(--fg-2); background: var(--surface-2); border-radius: var(--radius-sm); padding: 5px 8px; }
.rv-forum-pin, .rv-forum-lock { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; padding: 2px 7px; border-radius: var(--radius-pill); }
.rv-forum-pin { color: var(--accent-ink); background: color-mix(in srgb, var(--accent) 14%, transparent); }
.rv-forum-lock { color: var(--muted-2); background: var(--surface-2); }

/* single thread */
.rv-forum-locked-note { font-size: 13px; color: var(--muted-2); background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 14px; }
.rv-forum-posts { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 14px; }
.rv-forum-post { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.rv-forum-post.op { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.rv-forum-post-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.rv-forum-avatar { flex: none; width: 30px; height: 30px; border-radius: 50%; color: #fff; font-size: 14px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
.rv-forum-post-who { display: flex; flex-direction: column; line-height: 1.25; flex: 1; }
.rv-forum-post-name { font-size: 14px; font-weight: 600; color: var(--fg); }
.rv-forum-post-time { font-size: 11.5px; color: var(--muted); }
.rv-forum-post-del { background: transparent; border: 1px solid var(--line); color: var(--muted-2); font-size: 12px; padding: 4px 10px; border-radius: var(--radius-sm); cursor: pointer; }
.rv-forum-post-del:hover { border-color: var(--danger); color: var(--danger); }
.rv-forum-post-body { font-size: 14.5px; color: var(--fg-2); line-height: 1.6; word-break: break-word; white-space: normal; }
.rv-forum-link { color: var(--accent-ink); text-decoration: none; word-break: break-all; }
.rv-forum-link:hover { text-decoration: underline; }

/* composer */
.rv-forum-composer { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; margin: 8px 0; display: flex; flex-direction: column; gap: 12px; }
.rv-forum-field { display: flex; flex-direction: column; gap: 6px; }
.rv-forum-label { font-size: 12.5px; font-weight: 600; color: var(--muted); }
.rv-forum-input, .rv-forum-textarea { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--fg); font-size: 14px; padding: 9px 12px; font-family: inherit; width: 100%; }
.rv-forum-textarea { resize: vertical; min-height: 60px; line-height: 1.5; }
.rv-forum-input:focus, .rv-forum-textarea:focus { outline: 2px solid var(--accent-ink); outline-offset: 1px; border-color: transparent; }
.rv-forum-composer-actions { display: flex; gap: 10px; }
.rv-forum-err { font-size: 13px; color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); border: 1px solid color-mix(in srgb, var(--danger) 35%, transparent); border-radius: var(--radius-sm); padding: 9px 12px; }

/* forum moderation */
.rv-forum-modlink { align-self: flex-start; background: transparent; border: 1px solid var(--line); color: var(--muted); font-size: 12px; font-weight: 600; padding: 5px 12px; border-radius: var(--radius-pill); cursor: pointer; margin-top: -4px; transition: color 0.12s, border-color 0.12s; }
.rv-forum-modlink:hover { color: var(--fg-2); border-color: var(--accent-2); }
.rv-forum-mod-queue { display: flex; flex-direction: column; gap: 12px; }
.rv-forum-mod-item { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px 16px; }
.rv-forum-mod-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.rv-forum-mod-badge { font-size: 12px; font-weight: 700; color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); border-radius: var(--radius-pill); padding: 3px 10px; }
.rv-forum-mod-loc { font-size: 12px; color: var(--muted); }
.rv-forum-mod-author { font-size: 13px; font-weight: 600; color: var(--fg); margin-bottom: 4px; }
.rv-forum-mod-reasons { margin-top: 10px; background: var(--surface-2); border-radius: var(--radius-sm); padding: 8px 12px; }
.rv-forum-mod-reasons-h { font-size: 11.5px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
.rv-forum-mod-reason { font-size: 13px; color: var(--fg-2); }
.rv-forum-mod-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.rv-forum-mod-btn { background: var(--surface-2); border: 1px solid var(--line); color: var(--fg-2); font-size: 12.5px; font-weight: 600; padding: 6px 12px; border-radius: var(--radius-sm); cursor: pointer; transition: border-color 0.12s, color 0.12s; }
.rv-forum-mod-btn:hover { border-color: var(--accent-2); color: var(--fg); }
.rv-forum-mod-btn.danger:hover { border-color: var(--danger); color: var(--danger); }
.rv-forum-mod-btn.quiet { color: var(--muted); }

/* Star reviews on book cards */
.rv-stars { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0 6px; margin-top: 2px; }
.rv-stars-row { display: inline-flex; gap: 0; }
.rv-stars-row .rv-star { padding: 5px; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--radius-sm); }
.rv-star { background: none; border: 0; padding: 0; cursor: pointer; line-height: 0; color: color-mix(in srgb, var(--muted-2) 78%, var(--surface)); transition: color 0.1s, transform 0.08s; } /* dimmer than a filled star, but still 3:1 against the card */
.rv-star svg { width: 13px; height: 13px; display: block; }
.rv-stars-row .rv-star svg { width: 14px; height: 14px; }
.rv-stars-row .rv-star:focus-visible { outline-offset: -2px; } /* the card clips anything outside it */
.rv-star:hover { transform: scale(1.15); }
.rv-star.on { color: var(--accent-2); }
.rv-star.mine { color: var(--accent-ink); }
.rv-stars.rated .rv-star.on { color: var(--accent-ink); }
.rv-stars-count { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; min-width: 12px; }
.rv-mini-toast { position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%); background: var(--surface-2); color: var(--fg); border: 1px solid var(--line); border-radius: 10px; padding: 9px 15px; font-size: 13px; z-index: 70; box-shadow: 0 6px 20px rgba(0,0,0,0.45); }

/* Toolbar account button (BiB profile) */
.rv-account-btn { position: relative; }
.rv-account-btn.signed svg { display: none; }
.rv-account-av-mini { display: none; width: 22px; height: 22px; border-radius: 50%; color: var(--on-accent); font-size: 12px; font-weight: 700; align-items: center; justify-content: center; }
.rv-account-btn.signed .rv-account-av-mini { display: flex; }

/* Quests view */
/* Custom views (quests, leaderboard) render a single centered column, not a card grid. */
.rv-grid[data-style="custom"] { display: block; }
.rv-grid[data-style="custom"] .rv-quests { max-width: 720px; margin: 0 auto; }
.rv-quests { display: flex; flex-direction: column; gap: 16px; }
.rv-quests-head { display: flex; align-items: center; gap: 16px; background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 18px 20px; }
.rv-quests-level { flex: none; text-align: center; background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; padding: 10px 16px; min-width: 74px; }
.rv-quests-lvl-n { font-size: 20px; font-weight: 800; color: var(--accent-ink); letter-spacing: -0.5px; }
.rv-quests-lvl-l { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.rv-quests-xpwrap { flex: 1; }
.rv-quests-title { font-size: 19px; font-weight: 700; color: var(--fg); }
.rv-quests-sub { font-size: 12.5px; color: var(--muted); margin: 2px 0 8px; }
.rv-quests-xp { height: 8px; background: var(--surface-2); border-radius: 999px; overflow: hidden; }
.rv-quests-xp span { display: block; height: 100%; background: linear-gradient(90deg, var(--accent-2), var(--accent)); border-radius: 999px; transition: width 0.4s ease; }
.rv-quests-list { display: flex; flex-direction: column; gap: 10px; }
.rv-quest { display: flex; align-items: center; gap: 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 14px 16px; }
.rv-quest.done { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.rv-quest-check { flex: none; width: 30px; height: 30px; border-radius: 50%; border: 2px solid var(--line); display: flex; align-items: center; justify-content: center; color: var(--on-accent); }
.rv-quest.done .rv-quest-check { background: var(--accent); border-color: var(--accent); }
.rv-quest-check svg { width: 16px; height: 16px; }
.rv-quest-main { flex: 1; }
.rv-quest-title { font-size: 15px; font-weight: 600; color: var(--fg); }
.rv-quest-desc { font-size: 12.5px; color: var(--muted); margin: 1px 0 8px; }
.rv-quest-prog { height: 5px; background: var(--surface-2); border-radius: 999px; overflow: hidden; margin-bottom: 5px; }
.rv-quest-prog span { display: block; height: 100%; background: var(--accent-2); border-radius: 999px; transition: width 0.3s ease; }
.rv-quest.done .rv-quest-prog span { background: var(--accent); }
.rv-quest-count { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* seasonal collectible: a pumpkin badge in place of the check, and a small tag by the title */
.rv-quest-seasonal .rv-quest-check { color: var(--accent-ink); }
.rv-quest-seasonal.done .rv-quest-check { color: var(--on-accent); }
.rv-quest-seasonal .rv-quest-check svg { width: 18px; height: 18px; }
.rv-quest-tag { display: inline-block; margin-left: 8px; padding: 1px 8px; border-radius: 999px; background: var(--surface-2); color: var(--accent-ink); font-size: 11px; font-weight: 600; vertical-align: 2px; }
.rv-miles { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.rv-miles-title { margin: 0; font-size: 16px; font-weight: 700; color: var(--fg); }
.rv-miles-sub { font-size: 12.5px; color: var(--muted); margin: -4px 0 2px; }
.rv-mile { display: flex; align-items: center; gap: 14px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; padding: 12px 16px; }
.rv-mile-main { flex: 1; min-width: 0; }
.rv-mile-label { font-size: 13.5px; color: var(--fg-2); margin-bottom: 6px; font-variant-numeric: tabular-nums; }
.rv-mile-marks { display: flex; gap: 5px; flex: none; }
.rv-mile-marks span { width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid var(--line); }
.rv-mile-marks span.on { background: var(--accent); border-color: var(--accent); }
.rv-quest-toast { position: fixed; left: 50%; bottom: 26px; transform: translate(-50%, 12px); background: var(--surface-2); color: var(--fg); border: 1px solid var(--accent-2); border-radius: 12px; padding: 11px 18px; font-size: 14px; font-weight: 600; z-index: 80; box-shadow: 0 8px 26px rgba(0,0,0,0.5); opacity: 0; pointer-events: none; transition: opacity 0.25s, transform 0.25s; }
.rv-quest-toast.show { opacity: 1; transform: translate(-50%, 0); }

/* Leaderboard view */
.rv-grid[data-style="custom"] .rv-lb { max-width: 640px; margin: 0 auto; }

/* --- All shortcuts (app/all-shortcuts.js) ---------------------------------- */
.rv-grid[data-style="custom"] .rv-allsc { max-width: 720px; margin: 0 auto; }
.rv-allsc { display: flex; flex-direction: column; gap: 12px; }
.rv-allsc-intro { color: var(--fg-2); font-size: 14px; line-height: 1.5; margin: 0; }
.rv-allsc-sum { color: var(--muted-2); font-size: 13px; margin: 0; }
.rv-allsc-note { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 14px; padding: 12px 14px; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius-lg); color: var(--fg); font-size: 13px; line-height: 1.45; }
.rv-allsc-note > span { flex: 1 1 260px; }
.rv-allsc-addall { align-self: flex-start; }
.rv-allsc-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.rv-allsc-item { display: flex; align-items: center; gap: 14px; padding: 10px 12px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); }
.rv-allsc-item.off { border-style: dashed; border-color: var(--line-strong); }
.rv-allsc-icon { display: flex; align-items: center; justify-content: center; flex: none; width: 40px; height: 40px; border: 1px solid var(--line); border-radius: 50%; color: var(--icon-tint); background: var(--bg); }
.rv-allsc-icon svg { width: 20px; height: 20px; }
.rv-allsc-text { display: flex; flex-direction: column; gap: 3px; flex: 1 1 auto; min-width: 0; }
.rv-allsc-name { color: var(--fg); font-size: 14px; font-weight: 600; }
.rv-allsc-state { display: inline-flex; align-items: center; gap: 5px; color: var(--muted-2); font-size: 12.5px; }
.rv-allsc-state svg { width: 14px; height: 14px; flex: none; }
.rv-allsc-item:not(.off) .rv-allsc-state { color: var(--fg-2); }
.rv-allsc-item:not(.off) .rv-allsc-state svg { color: var(--accent-ink); }
.rv-allsc-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; flex: none; }
.rv-allsc-btn { min-height: 34px; padding: 0 14px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: transparent; color: var(--fg); font: inherit; font-size: 13px; cursor: pointer; }
.rv-allsc-btn:hover { background: var(--surface-2); }
.rv-allsc-add { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
.rv-allsc-add:hover { background: var(--accent); filter: brightness(1.06); }
@media (any-pointer: coarse) { .rv-allsc-btn { min-height: 44px; } }
@media (max-width: 560px) {
	.rv-allsc-item { flex-wrap: wrap; }
	.rv-allsc-acts { flex: 1 1 100%; justify-content: flex-start; padding-left: 54px; }
}
/* the first-removal tip in the toast sits on its own line */
.rv-sctoast { width: max-content; }
.rv-sctoast .rv-update-msg { line-height: 1.45; flex: 1 1 auto; min-width: 0; }
.rv-sctoast-tip { display: block; color: var(--fg-2); }
.rv-lb { display: flex; flex-direction: column; gap: 14px; }
.rv-lb-title { font-size: 24px; font-weight: 800; letter-spacing: -0.5px; margin: 0; color: var(--fg); }
.rv-lb-sub { font-size: 13.5px; color: var(--muted); margin: -6px 0 4px; line-height: 1.5; }
.rv-lb-note { font-size: 13.5px; color: var(--muted); margin: 0; }
.rv-lb-mecard { background: var(--surface); border: 1px solid var(--line); border-radius: 14px; padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.rv-lb-mestat { display: flex; align-items: baseline; gap: 10px; }
.rv-lb-merank { font-size: 22px; font-weight: 800; color: var(--accent-ink); }
.rv-lb-mesub { font-size: 13px; color: var(--muted); }
.rv-lb-handle { display: flex; gap: 8px; }
.rv-lb-input { flex: 1; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); color: var(--fg); font-size: 14px; padding: 9px 12px; font-family: inherit; }
.rv-lb-input:focus { outline: 2px solid var(--accent-ink); outline-offset: 1px; border-color: transparent; }
.rv-lb-save { background: var(--accent); color: var(--on-accent); border: 1px solid var(--accent-2); font-weight: 600; font-size: 14px; padding: 9px 16px; border-radius: var(--radius-sm); cursor: pointer; white-space: nowrap; }
.rv-lb-save:disabled { opacity: 0.6; }
.rv-lb-clear { align-self: flex-start; background: transparent; border: 1px solid var(--line); color: var(--muted-2); font-size: 12px; padding: 5px 12px; border-radius: var(--radius-pill); cursor: pointer; }
.rv-lb-clear:hover { border-color: var(--danger); color: var(--danger); }
.rv-lb-err { font-size: 13px; color: var(--danger); }
.rv-lb-list { display: flex; flex-direction: column; gap: 4px; }
.rv-lb-loading, .rv-lb-empty { color: var(--muted); font-size: 14px; padding: 16px 4px; text-align: center; }
.rv-lb-row { display: flex; align-items: center; gap: 14px; padding: 11px 16px; border-radius: 10px; background: var(--surface); border: 1px solid var(--line); }
.rv-lb-row.rv-lb-head { background: transparent; border: 0; padding: 4px 16px; font-size: 11px; text-transform: uppercase; letter-spacing: 0.6px; color: var(--faint); font-weight: 700; }
.rv-lb-row.you { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.rv-lb-rank { flex: none; width: 34px; display: flex; align-items: center; justify-content: center; }
.rv-lb-rank-n { font-size: 14px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.rv-lb-medal { width: 26px; height: 26px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 800; color: #16130a; }
.rv-lb-medal.m1 { background: #e9c46a; } .rv-lb-medal.m2 { background: #cfd3d8; } .rv-lb-medal.m3 { background: #d69256; }
.rv-lb-name { flex: 1; font-size: 15px; font-weight: 600; color: var(--fg); word-break: break-word; }
.rv-lb-head .rv-lb-name { font-weight: 700; }
.rv-lb-score { flex: none; font-size: 15px; font-weight: 700; color: var(--accent-ink); font-variant-numeric: tabular-nums; }
.rv-lb-head .rv-lb-score { color: var(--faint); font-weight: 700; font-size: 11px; }

/* forum verified-account composer states */
.rv-forum-gate { font-size: 13.5px; color: var(--muted); line-height: 1.55; margin: 0; }
.rv-forum-postingas { font-size: 12.5px; color: var(--accent-ink); font-weight: 600; margin-bottom: 2px; }
/* leaderboard: contributor breakdown */
.rv-lb-namewrap { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.rv-lb-break { font-size: 11.5px; color: var(--muted); margin-top: 1px; }

/* forum moderator management (owner-only) */
.rv-forum-modmanage { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.rv-forum-mod-h { font-size: 16px; font-weight: 700; color: var(--fg); margin: 0 0 6px; }
.rv-forum-modlist { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.rv-forum-modrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px; }
.rv-forum-modname { font-size: 14px; font-weight: 600; color: var(--fg); }

/* Moderation audit trail */
.rv-forum-modaudit { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.rv-forum-auditlist { display: flex; flex-direction: column; gap: 4px; margin-top: 10px; }
.rv-forum-auditrow { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 8px; background: var(--surface); border: 1px solid var(--line); border-radius: 9px; padding: 8px 12px; font-size: 13px; }
.rv-forum-audit-act { font-weight: 700; color: var(--accent, var(--fg)); }
.rv-forum-audit-by { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--fg); opacity: 0.85; }
.rv-forum-audit-detail { color: var(--fg); opacity: 0.7; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-forum-audit-when { color: var(--fg); opacity: 0.5; font-size: 12px; margin-left: auto; white-space: nowrap; }

/* Animated wallpaper (app/wallpaper.js): a muted looping video between the image layer (::before,
   which holds the still frame) and the dim scrim (::after). Blur is applied inline. */
.rv-wallpaper-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
:root[data-perf="on"] .rv-wallpaper-video { filter: none !important; }

/* ---- Accessibility ------------------------------------------------------------------------ */
.rv-sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.rv-skip { position: fixed; top: 6px; left: 6px; z-index: 1000; padding: 8px 14px; border-radius: var(--radius-sm); background: var(--surface); color: var(--fg); border: 1px solid var(--accent-ink); font-weight: 600; text-decoration: none; transform: translateY(-200%); }
.rv-skip:focus { transform: none; }
.rv-content:focus { outline: none; }
.rv-folder-title { margin: 0; }
.rv-folder-title:focus { outline: none; }

/* Library cards: the name is the button; the whole card shows its focus ring. */
.rv-card-open { display: block; width: 100%; border: 0; background: none; font: inherit; color: inherit; text-align: inherit; cursor: pointer; }
.rv-card-tool .rv-card-open, .rv-card-app .rv-card-open { padding: 0; }
.rv-link-text .rv-card-open { padding: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rv-card-open:focus-visible { outline: none; }
.rv-card:has(.rv-card-open:focus-visible) { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-color: var(--accent-2); }

/* Bedazzled's resting border outranks the shared focus style, so it gets its own. */
:root[data-theme="bedazzled"] .rv-startsearch:focus-within { border-color: var(--accent-ink); box-shadow: 0 0 0 1px var(--accent-ink), 0 1px 4px rgba(0, 0, 0, 0.35); }

/* Light snowfall (Holiday Update; opt-in, in a season that has it). One layer of small dots
   behind the start page (over the wallpaper, under the clock, search and tiles), slid down with
   transform so only the compositor works, never over a tab or a tool. It moves in 3 px steps (10 a
   second), which reads the same and costs far less where there's no GPU. Three 20 s falls, then it
   fades out and stays gone, so it never runs past a minute. The content box clips it (overflow:
   clip, so nothing new scrolls) and isolates it, so z-index -1 keeps the layer above the box's own
   background and below everything in it; the start page's own background (the same --bg) steps
   aside so the snow shows. theme.js only sets data-snow in season and while moving wallpapers are
   allowed; Lite mode, Animations off and reduced motion turn it off. */
:root[data-snow="on"] .rv-content:has(> .rv-start:not([hidden])) { overflow: clip; isolation: isolate; }
:root[data-snow="on"] .rv-content:has(> .rv-start:not([hidden])) > .rv-start { background: transparent; }
:root[data-snow="on"] .rv-content:has(> .rv-start:not([hidden]))::after {
	content: ""; position: absolute; z-index: -1; left: 0; right: 0; top: -600px; height: calc(100% + 600px); pointer-events: none;
	--flake: rgba(255, 255, 255, 0.5);
	background-image: radial-gradient(circle at 30px 40px, var(--flake) 1.5px, transparent 2.5px), radial-gradient(circle at 150px 95px, var(--flake) 1px, transparent 2px), radial-gradient(circle at 262px 30px, var(--flake) 1.8px, transparent 2.8px), radial-gradient(circle at 90px 170px, var(--flake) 2px, transparent 3px), radial-gradient(circle at 222px 212px, var(--flake) 1.2px, transparent 2.2px), radial-gradient(circle at 312px 262px, var(--flake) 1.5px, transparent 2.5px), radial-gradient(circle at 40px 262px, var(--flake) 1px, transparent 2px);
	background-size: 340px 300px;
	animation: rv-snow 20s steps(200) 3, rv-snow-out 2s linear 58s forwards;
	will-change: transform;
}
:root[data-snow="on"][data-mode="light"] .rv-content:has(> .rv-start:not([hidden]))::after { --flake: rgba(63, 90, 130, 0.32); }
@keyframes rv-snow { from { transform: translateY(0); } to { transform: translateY(600px); } }
@keyframes rv-snow-out { to { opacity: 0; } }
:root[data-snow="on"][data-perf="on"] .rv-content:has(> .rv-start:not([hidden]))::after, :root[data-snow="on"][data-animations="off"] .rv-content:has(> .rv-start:not([hidden]))::after { content: none; }
@media (prefers-reduced-motion: reduce) {
	:root[data-snow="on"] .rv-content:has(> .rv-start:not([hidden]))::after { content: none; }
}

/* Short screens (200% and 400% zoom, landscape phones, the on-screen keyboard): away from the
   start page (which scrolls on its own), the top bars and the folder header scroll away with the
   content instead of eating the whole screen. */
@media (max-height: 450px) {
	.rv-root:has(#rv-start[hidden]) { height: auto; min-height: 100vh; min-height: 100dvh; width: 100%; overflow: visible; }
	:root:not(.rv-shell):has(#rv-start[hidden]), :root:not(.rv-shell):has(#rv-start[hidden]) > body { overflow-y: auto; height: auto; }
	.rv-root:has(#rv-start[hidden]) .rv-content { flex: none; height: auto; min-height: 100vh; min-height: 100dvh; }
	.rv-folder { position: relative; inset: auto; min-height: 100vh; min-height: 100dvh; }
	.rv-folder-head { flex-wrap: wrap; padding: 10px 16px 8px; }
	.rv-folder-search { min-width: 0; max-width: 100%; }
	.rv-grid { flex: none; overflow: visible; padding: 12px 16px 18px; }
	.rv-folder-cats { flex: none; }
}
@media (max-width: 400px) {
	.rv-folder-head { flex-wrap: wrap; }
	.rv-folder-search { min-width: 0; width: 100%; max-width: 100%; }
}

/* --- High Contrast look: 7:1 text, one yellow, solid surfaces and borders, nothing see-through or
   blurred, no background pictures, and a thick focus ring. The yellow holds whatever accent is
   picked: inline styles lose to !important (the selector is html[...] so the token readers in
   test/contrast.test.mjs and the desktop skip it). --- */
html[data-theme="contrast"] { --accent: #ffd60a !important; --accent-2: #ffe45c !important; --accent-ink: #ffd60a !important; --on-accent: #000000 !important; --icon-tint: #ffd60a !important; }
:root[data-theme="contrast"] *, :root[data-theme="contrast"] ::before, :root[data-theme="contrast"] ::after { -webkit-backdrop-filter: none !important; backdrop-filter: none !important; text-shadow: none !important; }
:root[data-theme="contrast"] :focus-visible { outline: 3px solid #ffd60a !important; outline-offset: 2px !important; }
/* a search field shows one ring, on the whole box */
:root[data-theme="contrast"] :is(.rv-startsearch, .rv-omnibox):focus-within { outline: 3px solid #ffd60a; outline-offset: 2px; }
:root[data-theme="contrast"] :is(.rv-startsearch, .rv-omnibox, .rv-isl-field) input:focus-visible { outline: none !important; }
:root[data-theme="contrast"] a { text-decoration: underline; text-underline-offset: 2px; }
:root[data-theme="contrast"] .rv-start::before, :root[data-theme="contrast"] .rv-start-inner::before, :root[data-theme="contrast"] .rv-start-inner::after { background: none !important; }
:root[data-theme="contrast"] :is(.rv-startsearch, .rv-omnibox, .rv-restore, .rv-shortcut-btn, .rv-card, .rv-btn, .rv-jumpback-cover) { border-color: var(--line-strong); }
:root[data-theme="contrast"] :is(.rv-tab.active, .rv-chip.active) { box-shadow: inset 0 -3px 0 #ffd60a; background: var(--surface-2); color: #fff; }
:root[data-theme="contrast"] .rv-jumpback-x { background: #000; border: 1px solid #fff; }
/* no pictures behind text: a wallpaper picked before or after the look stays hidden */
:root[data-theme="contrast"] :is(.rv-wallpaper, .rv-wallpaper-video) { display: none !important; }

/* Windows high contrast and other forced-colour modes. */
@media (forced-colors: active) {
	.rv-startsearch:focus-within, .rv-omnibox:focus-within { outline: 2px solid Highlight; outline-offset: 2px; }
	.rv-nav, .rv-newtab, .rv-tab-close, .rv-fav-star, .rv-jumpback-x, .rv-star { border: 1px solid ButtonText; }
	.rv-chip.active, .rv-tab.active { outline: 2px solid Highlight; }
	.rv-status { color: CanvasText !important; }
	.rv-statp { border: 1px solid CanvasText; }
	/* box-shadow rings vanish here, so every focus ring is a real outline */
	:focus-visible { outline: 2px solid Highlight !important; outline-offset: 2px; }
	.rv-restore, .rv-card, .rv-jumpback-cover { border: 1px solid CanvasText; }
	.rv-restore-x, .rv-jumpback-x { border: 1px solid ButtonText; }
}

/* --- Island Mode (docs/ISLAND-MODE.md). The pre-paint sets data-layout="island", so these hold before
   the island chunk arrives: no Classic bars and no second search box, the island's own strip, and a
   still pill with the brand dot until the real island takes its place (body.rv-isl-on). --- */
:root[data-layout="island"] .rv-tabstrip, :root[data-layout="island"] .rv-navbar, :root[data-layout="island"] .rv-bookmarksbar,
:root[data-layout="island"] .rv-pulltab, :root[data-layout="island"] .rv-startsearch, :root[data-layout="island"] .rv-music,
:root[data-layout="island"] .rv-update:not(.rv-sctoast) { display: none !important; }
:root[data-layout="island"] .rv-findbar { top: auto; bottom: 16px; }
/* The pill gets its own strip instead of covering the middle of a site's header, where search boxes
   live. data-isl comes from the pre-paint too: "b" puts the strip at the bottom, "t" (tucked) drops it. */
:root[data-layout="island"] .rv-root { padding-top: calc(60px + env(safe-area-inset-top)); }
:root[data-layout="island"][data-isl="b"] .rv-root { padding-top: 0; padding-bottom: calc(60px + env(safe-area-inset-bottom)); }
:root[data-layout="island"][data-isl="t"] .rv-root { padding-top: 0; }
:root[data-layout="island"][data-isl="b"] :is(.rv-update, .rv-mini-toast, .rv-quest-toast, .rv-findbar) { margin-bottom: 60px; }
/* The start scene: with no page open there is only the wallpaper (or the look's background) and the
   island, a little above the middle. The start page's own parts all live in the island instead. A soft
   vignette over a wallpaper, or a faint accent glow without one, leads the eye to it. */
:root[data-layout="island"] { --isl-cy: 42vh; }
:root[data-layout="island"] .rv-start > * { display: none !important; }
:root[data-layout="island"] .rv-start::before {
	content: ""; position: fixed; inset: 0; pointer-events: none;
	background: radial-gradient(ellipse min(640px, 80vw) min(260px, 30vh) at 50% var(--isl-cy), color-mix(in srgb, var(--accent) 14%, transparent), transparent 70%);
}
:root[data-layout="island"][data-mode="light"] .rv-start::before { background: radial-gradient(ellipse min(640px, 80vw) min(260px, 30vh) at 50% var(--isl-cy), color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%); }
:root[data-layout="island"][data-wallpaper="on"] .rv-start::before { background: radial-gradient(ellipse 120% 95% at 50% var(--isl-cy), transparent 35%, rgba(0, 0, 0, .38)); }
:root[data-layout="island"] body:not(.rv-isl-on) > .rv-root::after {
	content: ""; position: fixed; z-index: 9500; top: 8px; left: 50%; width: min(560px, calc(100vw - 32px)); height: 44px; margin-left: calc(min(560px, calc(100vw - 32px)) / -2);
	border-radius: 22px; background: radial-gradient(circle at 22px 50%, var(--accent) 0 8px, transparent 9px), var(--surface); box-shadow: 0 0 0 1px var(--line-strong);
}
:root[data-layout="island"]:has(#rv-start:not([hidden])) body:not(.rv-isl-on) > .rv-root::after { top: calc(var(--isl-cy) - 22px); }
