/* ==========================================================================
   Lake Mead Admin — App Shell
   Fixed sidebar + blurred sticky topbar + scrolling main region.

   Shell state lives as classes on <body>, set by shell.js:
     .is-collapsed  desktop icon rail
     .is-open       mobile drawer open
   ========================================================================== */

/* --- Frame ---------------------------------------------------------------- */
.app {
  min-height: 100vh;
  padding-left: var(--sidebar-w);
  transition: padding-left var(--t-base) var(--ease);
}
body.is-collapsed .app { padding-left: var(--sidebar-w-collapsed); }

/* ==========================================================================
   SIDEBAR
   ========================================================================== */
.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: var(--z-sidebar);
  width: var(--sidebar-w);
  display: flex;
  flex-direction: column;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--line);
  transition: width var(--t-base) var(--ease),
              transform var(--t-base) var(--ease),
              background var(--t-base) var(--ease);
}
body.is-collapsed .sidebar { width: var(--sidebar-w-collapsed); }

/* --- Brand ---------------------------------------------------------------- */
.sidebar__brand {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  height: var(--topbar-h);
  padding: 0 var(--sp-5);
  overflow: hidden;
}
.brand-mark {
  flex: 0 0 34px;
  width: 34px; height: 34px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  /* The aqua→blue diagonal is the signature gradient from the portfolio. */
  background: linear-gradient(135deg, var(--aqua), var(--blue));
  color: var(--on-accent);
  font-weight: var(--fw-heavy);
  font-size: var(--fs-md);
  letter-spacing: var(--track-tight);
}
.brand-name {
  font-size: var(--fs-lg);
  font-weight: var(--fw-heavy);
  letter-spacing: var(--track-tight);
  color: var(--ink);
  white-space: nowrap;
}
/* The rail toggle lives in the brand row on desktop. */
.sidebar__pin {
  margin-left: auto;
  width: 26px; height: 26px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-xs);
  color: var(--muted);
  font-size: var(--fs-sm);
  transition: background var(--t-base) var(--ease), color var(--t-base) var(--ease);
}
.sidebar__pin:hover { background: var(--sidebar-hover); color: var(--ink); }

/* --- Nav ------------------------------------------------------------------ */
.sidebar__nav {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--sp-2) var(--sp-3) var(--sp-5);
}

/* --- Collapsible sections -------------------------------------------------
   Each group is a <button> heading plus its list. Collapse state lives as a
   space-separated token list on <html> (data-nav-collapsed="apps pages"), set
   by the inline <head> snippet before first paint — so a collapsed section
   never flashes open on navigation. shell.js keeps it in sync afterwards.
   ------------------------------------------------------------------------- */
.nav-group {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  padding: var(--sp-5) var(--sp-3) var(--sp-2);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-heavy);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  text-align: left;
  cursor: pointer;
  transition: color var(--t-base) var(--ease);
}
.nav-group:hover { color: var(--ink); }
.nav-group__text { flex: 1 1 auto; }

.nav-group__caret {
  flex: 0 0 auto;
  font-size: 9px;
  opacity: .6;
  transition: transform var(--t-base) var(--ease), opacity var(--t-base) var(--ease);
}
.nav-group:hover .nav-group__caret { opacity: 1; }

/* Collapse state is carried by two inherited custom properties set on the
   section, NOT by repeating the selector list for every property that reacts
   to it. Custom properties inherit, so one rule reaches the list and the caret
   both — and adding a section costs one line below instead of one line in
   each of three selector lists. */
.nav-section {
  --list-h: 900px;      /* clears the tallest group; the transition eases from
                           the real height down, so this is not a visible jump */
  --list-op: 1;
  --caret-rot: 0deg;
}

/* THE ONLY PLACE SECTION SLUGS ARE LISTED. Add a section here and in
   tools/partials/sidebar.html; nothing else needs touching. */
html[data-nav-collapsed~="dashboards"]     .nav-section[data-section="dashboards"],
html[data-nav-collapsed~="interface"]      .nav-section[data-section="interface"],
html[data-nav-collapsed~="svgpacks"]       .nav-section[data-section="svgpacks"],
html[data-nav-collapsed~="design-gallery"] .nav-section[data-section="design-gallery"],
html[data-nav-collapsed~="tide-pool"]      .nav-section[data-section="tide-pool"],
html[data-nav-collapsed~="pages"]          .nav-section[data-section="pages"],
html[data-nav-collapsed~="forms"]          .nav-section[data-section="forms"],
html[data-nav-collapsed~="apps"]           .nav-section[data-section="apps"],
html[data-nav-collapsed~="business"]       .nav-section[data-section="business"],
html[data-nav-collapsed~="help"]           .nav-section[data-section="help"] {
  --list-h: 0px;
  --list-op: 0;
  --caret-rot: -90deg;
}

.nav-section__list {
  overflow: hidden;
  max-height: var(--list-h);
  opacity: var(--list-op);
  transition: max-height var(--t-base) var(--ease),
              opacity var(--t-base) var(--ease);
}
.nav-group__caret { transform: rotate(var(--caret-rot)); }

/* --- Rail -----------------------------------------------------------------
   In the icon rail there is no room for a heading, and collapse is ignored
   while railed — every section shows its icons — so the heading button has
   nothing left to do. It used to be *styled into* the divider (1px tall,
   transparent text, pointer-events off), which left ten invisible controls
   in the tab order and drew a stray rule above the very first icon.

   So the button leaves the rail entirely, exactly as .nav-link__text does,
   and the divider is drawn by the section itself — from the second section
   onward, which is what makes it a divider rather than a leading rule. */
body.is-collapsed .nav-group { display: none; }

body.is-collapsed .nav-section + .nav-section::before {
  content: "";
  display: block;
  height: 1px;
  margin: var(--sp-4);
  background: var(--line);
}
/* The rail ignores collapse entirely. `:not(.is-open)` ties this rule's
   specificity with the collapsed-slug rule above and wins on source order —
   and it stops matching the moment the mobile drawer opens, at which point
   the collapse choice applies again with no extra rule needed. */
body.is-collapsed:not(.is-open) .nav-section { --list-h: 900px; --list-op: 1; }

.nav-item { position: relative; }

.nav-link {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  margin-bottom: 2px;
  border-radius: var(--radius-pill);
  color: var(--sidebar-text);
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--t-base) var(--ease),
              color var(--t-base) var(--ease);
}
.nav-link:hover { background: var(--sidebar-hover); color: var(--sidebar-active); }

.nav-link__icon {
  flex: 0 0 20px;
  width: 20px;
  text-align: center;
  font-size: var(--fs-base);
  color: var(--muted);
  transition: color var(--t-base) var(--ease);
}
.nav-link:hover .nav-link__icon { color: var(--ink); }
.nav-link__text { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; }

/* Active state: the aqua pill, the one place the brand color asserts itself
   in the chrome. Ink-on-aqua rather than white, per the portfolio buttons. */
.nav-link.is-active {
  background: var(--aqua);
  color: var(--on-accent);
  font-weight: var(--fw-bold);
}
.nav-link.is-active .nav-link__icon { color: var(--on-accent); }

/* Caret for items owning a submenu. */
.nav-caret {
  flex: 0 0 auto;
  font-size: var(--fs-2xs);
  color: var(--muted);
  transition: transform var(--t-base) var(--ease);
}
.nav-item.is-expanded > .nav-link > .nav-caret { transform: rotate(90deg); }

/* Count/status pill on the right of a nav row. */
.nav-badge {
  flex: 0 0 auto;
  min-width: 20px;
  padding: 1px var(--sp-2);
  border-radius: var(--radius-pill);
  background: var(--blue);
  color: var(--white);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-heavy);
  text-align: center;
}
.nav-badge--aqua { background: var(--aqua); color: var(--on-accent); }
.nav-badge--rose { background: var(--rose); color: var(--white); }

/* --- Submenu --------------------------------------------------------------
   Collapsed by max-height so the caret rotation and the slide share a
   transition. shell.js sets the pixel target for a smooth open. */
.nav-sub {
  overflow: hidden;
  max-height: 0;
  transition: max-height var(--t-base) var(--ease);
}
.nav-item.is-expanded > .nav-sub { max-height: 640px; }

.nav-sub .nav-link {
  padding-left: var(--sp-8);
  font-size: var(--fs-sm);
  font-weight: var(--fw-body);
}
/* Sub-items use a dot marker instead of an icon glyph. */
.nav-sub .nav-link::before {
  content: "";
  position: absolute;
  left: var(--sp-6);
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--muted);
  opacity: .5;
  transition: opacity var(--t-base) var(--ease), background var(--t-base) var(--ease);
}
.nav-sub .nav-item { position: relative; }
.nav-sub .nav-link:hover::before { opacity: 1; }
.nav-sub .nav-link.is-active::before { background: var(--on-accent); opacity: 1; }

/* --- Sidebar footer ------------------------------------------------------- */
.sidebar__foot {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  margin: 0 var(--sp-3) var(--sp-3);
  border-radius: var(--radius-card);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  overflow: hidden;
}
.sidebar__foot-meta { min-width: 0; }
.sidebar__foot-name {
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sidebar__foot-role {
  font-size: var(--fs-xs);
  color: var(--muted);
  white-space: nowrap;
}

/* --- Collapsed rail -------------------------------------------------------
   Everything textual disappears; icons center. Submenus are suppressed
   entirely rather than shown as flyouts, which keeps the rail predictable. */
body.is-collapsed .brand-name,
body.is-collapsed .sidebar__pin,
body.is-collapsed .nav-link__text,
body.is-collapsed .nav-caret,
body.is-collapsed .nav-badge,
body.is-collapsed .sidebar__foot-meta,
body.is-collapsed .nav-sub { display: none; }

body.is-collapsed .sidebar__brand,
body.is-collapsed .nav-link,
body.is-collapsed .sidebar__foot { justify-content: center; padding-inline: 0; }
body.is-collapsed .sidebar__nav { padding-inline: var(--sp-3); }
body.is-collapsed .nav-link { border-radius: var(--radius-card); }
body.is-collapsed .sidebar__foot { margin-inline: var(--sp-3); }

/* Rail tooltips — the label has to survive somewhere. */
body.is-collapsed .nav-link[data-label]:hover::after {
  content: attr(data-label);
  position: absolute;
  left: calc(100% + var(--sp-3));
  top: 50%;
  transform: translateY(-50%);
  z-index: var(--z-dropdown);
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--radius-xs);
  background: var(--ink);
  color: var(--paper);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  box-shadow: var(--shadow-md);
  pointer-events: none;
}

/* ==========================================================================
   TOPBAR
   Sticky + backdrop-blurred, matching both source sites' headers.
   ========================================================================== */
.topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-topbar);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  height: var(--topbar-h);
  padding: 0 var(--sp-6);
  background: var(--topbar-bg);
  border-bottom: 1px solid var(--line);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
}
.topbar__spacer { flex: 1 1 auto; }

/* --- Icon button ---------------------------------------------------------- */
.icon-btn {
  position: relative;
  flex: 0 0 auto;
  width: 38px; height: 38px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  color: var(--ink-soft);
  font-size: var(--fs-md);
  transition: background var(--t-base) var(--ease), color var(--t-base) var(--ease);
}
.icon-btn:hover { background: var(--sidebar-hover); color: var(--ink); }

/* Unread dot on the notification bell. */
.icon-btn__dot {
  position: absolute;
  top: 7px; right: 8px;
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--rose);
  border: 2px solid var(--paper);
}

/* --- Topbar search -------------------------------------------------------- */
.topbar__search {
  position: relative;
  flex: 0 1 340px;
}
.topbar__search i {
  position: absolute;
  left: var(--sp-4);
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-size: var(--fs-sm);
  pointer-events: none;
}
.topbar__search input {
  width: 100%;
  height: 38px;
  padding: 0 var(--sp-4) 0 var(--sp-8);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  color: var(--ink);
  font-size: var(--fs-base);
  transition: border-color var(--t-base) var(--ease),
              background var(--t-base) var(--ease),
              box-shadow var(--t-base) var(--ease);
}
.topbar__search input::placeholder { color: var(--muted); }
.topbar__search input:focus {
  border-color: var(--blue);
  background: var(--surface);
  box-shadow: 0 0 0 3px var(--blue-soft);
}
/* The ⌘K affordance, hidden once the field has focus. */
.topbar__search kbd {
  position: absolute;
  right: var(--sp-3);
  top: 50%;
  transform: translateY(-50%);
  padding: 2px var(--sp-2);
  border-radius: var(--radius-xs);
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  pointer-events: none;
  transition: opacity var(--t-fast) var(--ease);
}
.topbar__search input:focus ~ kbd { opacity: 0; }

/* ==========================================================================
   THEME SWITCHER
   Three-way segmented control (auto / day / night), ported in behavior from
   the earlier portfolio project's .theme-switcher.
   ========================================================================== */
.theme-switcher {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: var(--radius-pill);
  background: var(--surface-alt);
  border: 1px solid var(--line-soft);
}
.theme-choice {
  position: relative;              /* anchors the activation ring in toggles.css */
  width: 30px; height: 28px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-pill);
  color: var(--muted);
  font-size: var(--fs-sm);
  transition: background var(--t-base) var(--ease), color var(--t-base) var(--ease);
}
.theme-choice:hover { color: var(--ink); }
.theme-choice[aria-pressed="true"] {
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}

/* ==========================================================================
   MAIN REGION
   ========================================================================== */
.main {
  max-width: var(--content-max);
  padding: var(--sp-6);
}

/* --- Breadcrumb ----------------------------------------------------------- */
.breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--muted);
}
.breadcrumb li { display: flex; align-items: center; gap: var(--sp-2); }
.breadcrumb li + li::before { content: "/"; color: var(--line); }
.breadcrumb a { color: var(--muted); }
.breadcrumb a:hover { color: var(--blue); }
.breadcrumb [aria-current="page"] { color: var(--ink); font-weight: var(--fw-medium); }

/* --- Page header ---------------------------------------------------------- */
.page-head {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: var(--sp-4);
  margin: var(--sp-3) 0 var(--sp-6);
}
.page-head__title {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-heavy);
  letter-spacing: var(--track-tight);
  line-height: 1.15;
}
.page-head__sub {
  margin-top: var(--sp-1);
  color: var(--muted);
  font-size: var(--fs-md);
}
.page-head__actions {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

/* ==========================================================================
   MOBILE
   Below --bp-mobile the sidebar becomes an off-canvas drawer.
   ========================================================================== */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--z-backdrop);
  background: rgba(7, 19, 30, .5);
  opacity: 0;
  pointer-events: none;
  backdrop-filter: blur(2px);
  transition: opacity var(--t-base) var(--ease);
}

@media (max-width: 960px) {
  .app,
  body.is-collapsed .app { padding-left: 0; }

  .sidebar { transform: translateX(-100%); box-shadow: none; }
  /* The drawer always shows full width, even if the rail was collapsed. */
  body.is-open .sidebar {
    width: var(--sidebar-w);
    transform: none;
    box-shadow: var(--shadow-lg);
  }
  body.is-open .backdrop { opacity: 1; pointer-events: auto; }

  /* Restore everything the rail hid — the drawer is never a rail. */
  body.is-collapsed.is-open .brand-name,
  body.is-collapsed.is-open .nav-link__text,
  body.is-collapsed.is-open .nav-caret,
  body.is-collapsed.is-open .nav-badge,
  body.is-collapsed.is-open .sidebar__foot-meta { display: block; }
  body.is-collapsed.is-open .nav-sub { display: block; }
  body.is-collapsed.is-open .nav-link { justify-content: flex-start; padding-inline: var(--sp-3); border-radius: var(--radius-pill); }
  body.is-collapsed.is-open .sidebar__brand { justify-content: flex-start; padding-inline: var(--sp-5); }
  body.is-collapsed.is-open .sidebar__foot { justify-content: flex-start; padding-inline: var(--sp-4); }
  body.is-collapsed.is-open .nav-group {
    height: auto; margin: 0; padding: var(--sp-5) var(--sp-3) var(--sp-2);
    background: none; color: var(--muted);
    pointer-events: auto; cursor: pointer;
  }
  /* No drawer rule is needed: the rail override above is gated on
     :not(.is-open), so opening the drawer restores the collapse choice. */

  .topbar { padding: 0 var(--sp-4); }
  .topbar__search { display: none; }
  .main { padding: var(--sp-4); }
  .page-head__title { font-size: var(--fs-2xl); }
}

/* Phone: the topbar has to be allowed a second row.
   ADDED — not in the upstream theme.

   .topbar is a fixed-height, non-wrapping flex row, which holds only while its
   contents fit. On a 390px phone they do not, and because most of the items
   are `flex: 0 0 auto`, the overflow has nowhere to go: items spill past the
   bar's own padding and sit on top of each other. On the device-test page the
   address field (the one shrinkable item) collapsed to the width of its icon
   while the Test Website button overlapped the appearance switcher; on the
   home page the palette button ended up flush against the screen edge.

   The theme's own answer was the rule below — hide the switcher, the palette
   and the home link under 560px. That is why this never showed up before.
   Hiding them is not an option here: they are the only way to change theme or
   background on a phone, and there is no settings screen to move them to.

   So the bar wraps and grows instead. Individual pages decide what goes on
   which row by giving an item an `order` (see .dt-url-form). */
@media (max-width: 720px) {
  .topbar {
    height: auto;
    flex-wrap: wrap;
    row-gap: 10px;
    padding: 10px var(--sp-4);
  }
}

@media (max-width: 560px) {
  .page-head__actions { width: 100%; margin-left: 0; }
}

/* ==========================================================================
   BACK TO TOP
   Bottom-right, revealed once the page is long enough and scrolled far enough
   to be worth it. The ring around it is the scroll position, so the control
   reports progress as well as offering the trip back.
   ========================================================================== */
.to-top {
  --to-top-size: 48px;
  position: fixed;
  right: var(--sp-5);
  bottom: var(--sp-5);
  /* Below the customizer so the panel covers it rather than punching through,
     and below toasts, which own this corner when they are up. */
  z-index: var(--z-dropdown);
  width: var(--to-top-size);
  height: var(--to-top-size);
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: var(--aqua);
  color: var(--on-accent);
  box-shadow: var(--shadow-md);
  cursor: pointer;
  opacity: 0;
  transform: translateY(10px) scale(.9);
  transition: opacity var(--t-base) var(--ease),
              transform var(--t-base) var(--ease),
              background var(--t-base) var(--ease);
}
/* [hidden] would remove it from layout before the transition could run, so
   shell.js only clears `hidden` once — .is-visible does the animating. */
.to-top.is-visible { opacity: 1; transform: none; }
.to-top:hover { background: var(--aqua-deep); }
.to-top:hover .to-top__chev { transform: translateY(-1px); }
.to-top:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 2px var(--on-accent), var(--shadow-md);
}

.to-top__ring {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  transform: rotate(-90deg);   /* start the sweep at 12 o'clock */
  pointer-events: none;
}
.to-top__ring circle {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
}
.to-top__track { stroke: var(--on-accent); opacity: .25; }
.to-top__fill {
  stroke: var(--on-accent);
  stroke-dasharray: 100;
  /* Full offset = empty ring. shell.js writes the live value as an inline
     style, which outranks this rule. */
  stroke-dashoffset: 100;
}

/* The Dual Arc treatment, borrowed from the gallery design of the same name:
   a faint full track, an outer arc, and a second arc inside it turning the
   other way. One deliberate difference from the gallery version — there the
   outer arc spins too, but here it carries the scroll position, so it is the
   INNER arc that turns. The control keeps its meaning and gains the motion.

   Every color here is --on-accent, which the customizer rewrites at runtime
   along with --aqua, so the whole control follows the picker. */
.to-top__inner {
  stroke: var(--on-accent);
  opacity: .7;
  stroke-dasharray: 100;
  stroke-dashoffset: 76;            /* ~24% of the circumference drawn */
  /* transform-box defaults to view-box for SVG, so 50% 50% resolves to the
     center of the viewBox — which is also this circle's center. */
  transform-origin: 50% 50%;
  animation: to-top-spin 4.4s linear infinite reverse;
}
/* Stated through .to-top__ring so it outranks the shared
   `.to-top__ring circle { stroke-width: 2.5 }` above — the inner arc
   is the quieter of the two. */
.to-top__ring .to-top__inner { stroke-width: 2; }
@keyframes to-top-spin { to { transform: rotate(360deg); } }

.to-top__chev {
  position: relative;
  width: 22px; height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--t-base) var(--ease);
}
/* The same blink-and-fade run the customizer's close tab uses, turned to point
   up. Constant and small at rest; hover only speeds it up, per the gallery's
   first design law. */
.to-top__a, .to-top__b { animation: to-top-run 2.4s ease-in infinite; }
.to-top__b { animation-delay: 1.2s; }
.to-top:hover .to-top__a,
.to-top:hover .to-top__b { animation-duration: .9s; }
.to-top:hover .to-top__b { animation-delay: .45s; }
@keyframes to-top-run {
  0%   { transform: translateY(2px); opacity: 0; }
  40%  { opacity: 1; }
  100% { transform: translateY(-3px); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .to-top { transition: opacity var(--t-base) var(--ease); transform: none; }
  .to-top__a, .to-top__b { animation: none; opacity: 1; }
  /* The inner arc is decoration, so it stops. The outer arc still tracks
     scroll, because that is information rather than motion. */
  .to-top__inner { animation: none; }
  .to-top:hover .to-top__chev { transform: none; }
}

@media (max-width: 480px) {
  .to-top { --to-top-size: 44px; right: var(--sp-4); bottom: var(--sp-4); }
}

@media print { .to-top { display: none !important; } }
