/**
 * OTROTL Network Overlay - Shared Frontend Styles
 * ================================================
 * Served from a shared mount at /SHARED_NETWORK_OVERLAY/css/
 * Source of truth: tools/SHARED_NETWORK_OVERLAY/frontend/css/
 *
 * Design rules:
 *   - ALL rem units, ZERO px values
 *   - Mobile-first: 360px (22.5rem) minimum viewport
 *   - Touch targets: min 2.75rem
 *   - Dark/Light support via `dark` class on <html>
 *   - Font Awesome icons assumed available
 *   - Designed to scale to 100+ network sites
 *
 * Site integration contract:
 *   Set --otrotl-trigger-accent on :root to tint the trigger icon
 *   with the site's brand accent color. Falls back to #3b82f6 blue.
 *
 * Host brand bridge (2026-07, SSO branding tokens):
 *   Every accent below reads the host site's --site-* brand token with the
 *   previous literal as its var() fallback. A site opts in simply by linking
 *   its SSO branding sheet LAST in <head>:
 *
 *     <link rel="stylesheet" href="/auth/api/branding/theme.css">
 *
 *   Unopted sites serve a stub that defines nothing, so every var() below
 *   resolves to its literal fallback and the overlay computes exactly as it
 *   did before this bridge existed. Host pages that cannot add the <link>
 *   (we do not own their <head>) are covered by otrotl-brand-hydrate.js,
 *   which sets the same tokens via CSSOM.
 *
 *   Most of what is consumed here is theme-INVARIANT (-fill, -hover, -tint,
 *   -soft, on-accent): one value in both theme blocks, so it cannot
 *   desynchronise from our palette. The theme-VARYING tokens
 *   (--site-accent-ink, --site-accent-glow, --icon-*) are deliberately NOT
 *   used: they flip on `prefers-color-scheme: dark`, but this overlay's dark
 *   palette flips ONLY on html.dark / html[data-theme="dark"]. On a dark-OS
 *   host that sets neither marker the overlay paints its LIGHT panel, so a
 *   dark-variant ink would land on a white surface.
 *
 *   --site-accent-strong is the ONE exception: it is theme-VARYING too, but
 *   it is also the only token clamped for contrast as a non-text indicator,
 *   which is exactly the role our focus rings, the active-view glyph and the
 *   trigger need. It is therefore consumed through the --otrotl-accent-strong
 *   / --otrotl-accent-strong-tv aliases, which are gated back to their
 *   literals in the single state where the desynchronisation above applies.
 *   Do NOT read --site-accent-strong directly; use the aliases.
 *
 *   Markup (inside a .nav-brand-group or equivalent flex/grid zone):
 *     <button type="button" id="otrotl-network-btn"
 *             class="otrotl-network-trigger"
 *             onclick="OTROTLNetwork.open()"
 *             aria-label="Open OTROTL Network Overlay">
 *       <span class="otrotl-network-trigger__icon">
 *         <i class="fa-solid fa-diagram-project" aria-hidden="true"></i>
 *       </span>
 *       <span class="otrotl-network-trigger__badge" data-otrotl-count hidden></span>
 *     </button>
 */

/* ==========================================================================
   CSS Custom Properties
   ========================================================================== */

:root {
  /* --- overlay geometry ---
     Fluid width: 92vw up to a hard cap of 100rem (1600px) so the panel
     uses ~all the horizontal space on phones/tablets, breathes on
     laptops, and doesn't become a cinemascope strip on 4K. */
  --otrotl-panel-max-width: min(92vw, 100rem);
  --otrotl-panel-max-height: 85vh;
  /* Card grid: minimum card width before we wrap to a new row.
     Override per-site if a brand wants denser/looser packing. */
  --otrotl-card-min-width: 16rem;
  --otrotl-card-min-width-list: 24rem;
  --otrotl-z-backdrop: 9999;
  --otrotl-z-panel: 10000;
  --otrotl-z-toast: 10001;

  /* --- brand ring / indicator ink (gated: see the block after :root) ---
     --site-accent-strong is one of the branding sheet's THEME-VARYING tokens,
     so it is never read directly; every consumer goes through these two
     aliases, which the gate below neutralises in the one state where the
     sheet's theme and ours disagree. The two literals differ because the
     Smart-TV focus treatment has always used a brighter blue. */
  --otrotl-accent-strong: var(--site-accent-strong, #3b82f6);
  --otrotl-accent-strong-tv: var(--site-accent-strong, #60a5fa);

  /* --- trigger accent (override per-site for brand tint) ---
     Bridged to the host's SSO brand tokens. A host :root rule that sets
     --otrotl-trigger-accent itself still wins by source order, exactly as
     it did before, so the documented per-site knob is unchanged. */
  --otrotl-trigger-accent: var(--otrotl-accent-strong, #3b82f6);
  --otrotl-trigger-accent-soft: var(--site-accent-tint, rgba(59, 130, 246, 0.12));
  --otrotl-trigger-accent-ring: var(--site-accent-soft, rgba(59, 130, 246, 0.35));

  /* --- light-mode palette (default) --- */
  --otrotl-bg-panel: #ffffff;
  --otrotl-bg-card: #ffffff;
  --otrotl-bg-card-hover: #f8fafc;
  --otrotl-bg-header: #ffffff;
  --otrotl-bg-footer: #ffffff;
  --otrotl-bg-trigger: rgba(241, 245, 249, 0.9);
  --otrotl-bg-trigger-hover: rgba(226, 232, 240, 1);
  --otrotl-bg-input: #f1f5f9;

  --otrotl-text-primary: #0f172a;
  --otrotl-text-secondary: #475569;
  --otrotl-text-muted: #94a3b8;

  --otrotl-border: #e2e8f0;
  --otrotl-border-hover: #cbd5e1;

  --otrotl-shadow-panel: 0 1.25rem 3.75rem -0.75rem rgba(0, 0, 0, 0.25);
  --otrotl-shadow-card: 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.06);
  --otrotl-shadow-card-hover: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1);
}

/* --- theme-varying brand tokens: the one desynchronised state ---
   The branding sheet serves its DARK block whenever the OS prefers dark and
   the host has marked NEITHER theme channel. The overlay's own dark palette
   (below) needs an explicit html.dark / html[data-theme="dark"] marker, so in
   exactly that state the sheet has switched and we have not: a dark-variant
   accent would be painted onto our light panel, where it can fall under the
   contrast floor for a focus ring or the trigger glyph.

   There is no pre-paint stamp available to close the gap the usual way — this
   overlay owns no page of its own, and stamping the HOST document would
   hijack the host site's theme. So instead the aliases fall back to their
   literals here, which is exactly how an unopted site already renders. Every
   other state has the sheet and the overlay in agreement and keeps the brand
   colour. The :not() guards mirror the ones the branding sheet uses itself. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]):not(.dark):not(.light) {
    --otrotl-accent-strong: #3b82f6;
    --otrotl-accent-strong-tv: #60a5fa;
  }
}

/* --- dark-mode palette --- */
:is(html.dark, html[data-theme="dark"]) {
  --otrotl-bg-panel: #0f172a;
  --otrotl-bg-card: #1e293b;
  --otrotl-bg-card-hover: #263548;
  --otrotl-bg-header: #0f172a;
  --otrotl-bg-footer: #0f172a;
  --otrotl-bg-trigger: rgba(30, 41, 59, 0.7);
  --otrotl-bg-trigger-hover: rgba(51, 65, 85, 0.9);
  --otrotl-bg-input: #1e293b;

  --otrotl-text-primary: #f1f5f9;
  --otrotl-text-secondary: #94a3b8;
  --otrotl-text-muted: #64748b;

  --otrotl-border: #334155;
  --otrotl-border-hover: #475569;

  --otrotl-shadow-panel: 0 1.25rem 3.75rem -0.75rem rgba(0, 0, 0, 0.5);
  --otrotl-shadow-card: 0 0.0625rem 0.1875rem rgba(0, 0, 0, 0.2);
  --otrotl-shadow-card-hover: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.35);
}

/* ==========================================================================
   Trigger Button — polished (icon + badge, no wrapper needed)
   ========================================================================== */

.otrotl-network-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  padding: 0;
  border: 0.0625rem solid transparent;
  border-radius: 0.75rem;
  background: var(--otrotl-bg-trigger);
  color: var(--otrotl-trigger-accent);
  cursor: pointer;
  transition: transform 0.2s ease,
              background-color 0.2s ease,
              border-color 0.2s ease,
              box-shadow 0.2s ease;
  flex-shrink: 0;
  position: relative;
  z-index: 1;
}

.otrotl-network-trigger:hover {
  transform: scale(1.06);
  background: var(--otrotl-trigger-accent-soft);
  border-color: var(--otrotl-trigger-accent-ring);
  box-shadow: 0 0 0 0.1875rem var(--otrotl-trigger-accent-ring);
}

.otrotl-network-trigger:focus-visible {
  outline: 0.125rem solid var(--otrotl-trigger-accent);
  outline-offset: 0.125rem;
}

.otrotl-network-trigger:active {
  transform: scale(0.97);
}

/* --- Icon sub-element --- */

.otrotl-network-trigger__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.375rem;
  width: 1.5rem;
  height: 1.5rem;
  flex-shrink: 0;
}

/* --- Count badge (top-right) --- */

.otrotl-network-trigger__badge {
  position: absolute;
  top: -0.25rem;
  right: -0.25rem;
  min-width: 1.125rem;
  height: 1.125rem;
  padding: 0 0.25rem;
  border-radius: 1rem;
  background: var(--site-accent-fill, var(--otrotl-trigger-accent));
  color: var(--site-on-accent, #ffffff);
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1.125rem;
  text-align: center;
  pointer-events: none;
  box-shadow: 0 0.0625rem 0.25rem rgba(0, 0, 0, 0.15);
}

.otrotl-network-trigger__badge[hidden] {
  display: none;
}

/* ==========================================================================
   Backdrop
   ========================================================================== */

.otrotl-overlay-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(0.25rem);
  -webkit-backdrop-filter: blur(0.25rem);
  z-index: var(--otrotl-z-backdrop);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
}

.otrotl-overlay-backdrop.otrotl-active {
  opacity: 1;
  visibility: visible;
}

/* ==========================================================================
   Centered Modal Panel (was: left-sliding drawer)
   ========================================================================== */

.otrotl-overlay-panel {
  position: fixed;
  left: 50%;
  top: 50%;
  width: var(--otrotl-panel-max-width);
  max-height: var(--otrotl-panel-max-height);
  max-height: 85dvh;
  background: var(--otrotl-bg-panel);
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 1rem;
  box-shadow: var(--otrotl-shadow-panel);
  z-index: var(--otrotl-z-panel);
  display: flex;
  flex-direction: column;
  overflow: hidden;

  /* slide-up animation — starts slightly below center */
  transform: translate(-50%, -50%) translateY(2rem);
  opacity: 0;
  visibility: hidden;
  transition: transform 0.3s ease, opacity 0.3s ease, visibility 0.3s ease;
}

.otrotl-overlay-panel.otrotl-active {
  transform: translate(-50%, -50%) translateY(0);
  opacity: 1;
  visibility: visible;
}

/* ==========================================================================
   Panel Header
   ========================================================================== */

.otrotl-overlay-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1rem 1.25rem;
  border-bottom: 0.0625rem solid var(--otrotl-border);
  background: var(--otrotl-bg-header);
  flex-shrink: 0;
  gap: 0.75rem;
}

.otrotl-overlay-title {
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--otrotl-text-primary);
  white-space: nowrap;
  letter-spacing: 0.025em;
}

.otrotl-overlay-controls {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  margin-left: auto;
}

/* --- header icon buttons (grid/list toggle, close) --- */
.otrotl-view-btn,
.otrotl-close-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.5rem;
  background: transparent;
  color: var(--otrotl-text-muted);
  font-size: 0.875rem;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}

.otrotl-view-btn:hover,
.otrotl-close-btn:hover {
  color: var(--otrotl-text-primary);
  border-color: var(--otrotl-border-hover);
  background: var(--otrotl-bg-card-hover);
}

.otrotl-view-btn:focus-visible,
.otrotl-close-btn:focus-visible {
  outline: 0.125rem solid var(--otrotl-accent-strong, #3b82f6);
  outline-offset: 0.0625rem;
}

.otrotl-view-btn.otrotl-view-active {
  /* icon-only button: accent-strong is the >=3.0-vs-bg graphical token. */
  color: var(--otrotl-accent-strong, #3b82f6);
  border-color: var(--otrotl-accent-strong, #3b82f6);
  background: var(--site-accent-tint, rgba(59, 130, 246, 0.1));
}

.otrotl-close-btn:hover {
  color: #ef4444;
  border-color: #ef4444;
}

/* ==========================================================================
   Filter Bar (between header and body)
   ========================================================================== */

.otrotl-filter-bar {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0.75rem 1.25rem;
  border-bottom: 0.0625rem solid var(--otrotl-border);
  background: var(--otrotl-bg-header);
  flex-shrink: 0;
}

/* --- search input wrapper --- */
.otrotl-search-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.otrotl-search-icon {
  position: absolute;
  left: 0.75rem;
  color: var(--otrotl-text-muted);
  font-size: 0.875rem;
  pointer-events: none;
}

.otrotl-search-input {
  width: 100%;
  padding: 0.625rem 2.5rem 0.625rem 2.25rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.5rem;
  background: var(--otrotl-bg-input);
  color: var(--otrotl-text-primary);
  font-size: 0.875rem;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.otrotl-search-input::placeholder {
  color: var(--otrotl-text-muted);
}

.otrotl-search-input:focus {
  border-color: var(--otrotl-accent-strong, #3b82f6);
  box-shadow: 0 0 0 0.1875rem var(--site-accent-tint, rgba(59, 130, 246, 0.15));
}

.otrotl-search-clear {
  position: absolute;
  right: 0.5rem;
  display: none;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border: none;
  border-radius: 50%;
  background: var(--otrotl-border);
  color: var(--otrotl-text-secondary);
  font-size: 0.625rem;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.otrotl-search-clear.otrotl-visible {
  display: inline-flex;
}

.otrotl-search-clear:hover {
  background: var(--otrotl-border-hover);
  color: var(--otrotl-text-primary);
}

/* --- category pills row ---
   flex-wrap means every pill is visible regardless of viewport, no
   hidden horizontal scroll for users to discover. Wraps cleanly to
   1 row on wide screens, 2-3 rows on phones. */
.otrotl-category-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  padding-bottom: 0.125rem;
}

.otrotl-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.375rem 0.75rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 1.25rem;
  background: transparent;
  color: var(--otrotl-text-secondary);
  font-size: 0.75rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
  min-height: 2.75rem; /* DEV_GUIDE rule 6: touch target >= 2.75rem (Session 7 POLISH-3) */
}

.otrotl-pill:hover {
  border-color: var(--otrotl-border-hover);
  background: var(--otrotl-bg-card-hover);
  color: var(--otrotl-text-primary);
}

.otrotl-pill:focus-visible {
  outline: 0.125rem solid var(--otrotl-accent-strong, #3b82f6);
  outline-offset: 0.0625rem;
}

.otrotl-pill.otrotl-pill-active {
  background: var(--site-accent-fill, #3b82f6);
  border-color: var(--site-accent-fill, #3b82f6);
  color: var(--site-on-accent, #ffffff);
}

.otrotl-pill.otrotl-pill-active:hover {
  background: var(--site-accent-hover, #2563eb);
  border-color: var(--site-accent-hover, #2563eb);
  /* Same ink as the resting state: accent-hover is a shade of accent-fill, so
     re-deriving the label colour here would let it flip mid-interaction. */
  color: var(--site-on-accent, #ffffff);
}

.otrotl-pill-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.125rem;
  height: 1.125rem;
  padding: 0 0.25rem;
  border-radius: 0.5625rem;
  background: rgba(0, 0, 0, 0.08);
  font-size: 0.625rem;
  font-weight: 700;
}

.otrotl-pill.otrotl-pill-active .otrotl-pill-count {
  background: rgba(255, 255, 255, 0.25);
}

/* --- result count --- */
.otrotl-result-count {
  font-size: 0.75rem;
  color: var(--otrotl-text-muted);
  flex-shrink: 0;
}

/* ==========================================================================
   Panel Body (scrollable card area)
   ========================================================================== */

.otrotl-overlay-body {
  flex: 1;
  overflow-y: auto;
  /* Prevent any child (card, role-select, long description) from forcing
     horizontal overflow on the whole overlay body. */
  overflow-x: hidden;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
}

/* --- custom thin scrollbar --- */
.otrotl-overlay-body::-webkit-scrollbar {
  width: 0.375rem;
}

.otrotl-overlay-body::-webkit-scrollbar-track {
  background: transparent;
}

.otrotl-overlay-body::-webkit-scrollbar-thumb {
  background: var(--otrotl-border);
  border-radius: 0.1875rem;
}

.otrotl-overlay-body::-webkit-scrollbar-thumb:hover {
  background: var(--otrotl-border-hover);
}

/* Firefox scrollbar */
.otrotl-overlay-body {
  scrollbar-width: thin;
  scrollbar-color: var(--otrotl-border) transparent;
}

/* --- loading spinner --- */
.otrotl-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem 1rem;
  gap: 1rem;
  color: var(--otrotl-text-muted);
  font-size: 0.875rem;
}

.otrotl-loading .otrotl-spinner {
  width: 2rem;
  height: 2rem;
  border: 0.1875rem solid var(--otrotl-border);
  border-top-color: var(--otrotl-accent-strong, #3b82f6);
  border-radius: 50%;
  animation: otrotl-spin 0.7s linear infinite;
}

@keyframes otrotl-spin {
  to { transform: rotate(360deg); }
}

/* --- error / empty state --- */
.otrotl-error,
.otrotl-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 3rem 1rem;
  gap: 0.75rem;
  color: var(--otrotl-text-muted);
  text-align: center;
  font-size: 0.875rem;
}

.otrotl-error {
  color: #ef4444;
}

.otrotl-error i,
.otrotl-empty-state i {
  font-size: 1.5rem;
}

.otrotl-retry-btn,
.otrotl-clear-filters-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.5rem 1rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.5rem;
  background: transparent;
  color: var(--otrotl-text-secondary);
  font-size: 0.8125rem;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

/* --- per-site error chip (B-3) --- */
.otrotl-error-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.375rem;
  padding: 0.25rem 0.625rem;
  border: 0.0625rem solid rgba(239, 68, 68, 0.4);
  border-radius: 999rem;
  background: rgba(239, 68, 68, 0.08);
  color: #ef4444;
  font-size: 0.75rem;
  line-height: 1.2;
  max-width: 100%;
}

.otrotl-error-chip i {
  font-size: 0.75rem;
  flex-shrink: 0;
}

.otrotl-error-chip-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.otrotl-error-chip--orphan {
  margin: 0.5rem 1rem;
}

.otrotl-retry-btn:hover,
.otrotl-clear-filters-btn:hover {
  border-color: var(--otrotl-border-hover);
  color: var(--otrotl-text-primary);
}

/* ==========================================================================
   Grid / List View Containers — fluid auto-fill, scales to any width

   Key idea: the column count is derived from the CONTAINER WIDTH and a
   MINIMUM CARD WIDTH, not from hard-coded viewport breakpoints. That
   means the same layout works at 360px (phone), 1440px (laptop), and
   3840px (4K TV) with zero cut-off cards, zero horizontal scroll, and
   card widths that stay within a known readable band.

   auto-fill + minmax(<min>, 1fr):
     - fits as many <min>-wide tracks as possible into the container,
       then stretches each one equally (1fr) to consume the leftover.
     - Adding/removing a card never changes the width of the others.
     - Works identically for 5 sites or 500.
   ========================================================================== */

.otrotl-sites-grid {
  display: grid;
  gap: 0.75rem;
  /* min-width: 0 prevents grid blow-out when a card's content is wider
     than its track (long descriptions, role-selects on narrow phones). */
  min-width: 0;
  width: 100%;
}

.otrotl-sites-grid.otrotl-grid-view {
  grid-template-columns: repeat(auto-fill, minmax(var(--otrotl-card-min-width), 1fr));
}

.otrotl-sites-grid.otrotl-list-view {
  grid-template-columns: repeat(auto-fill, minmax(var(--otrotl-card-min-width-list), 1fr));
}

/* Phones with very narrow viewports: force single column so cards don't
   shrink below the 16rem minimum and clip content. */
@media (max-width: 22.5rem) {
  .otrotl-sites-grid.otrotl-grid-view,
  .otrotl-sites-grid.otrotl-list-view {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   Site Card
   ========================================================================== */

.otrotl-site-card {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 1rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.75rem;
  background: var(--otrotl-bg-card);
  box-shadow: var(--otrotl-shadow-card);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
  cursor: default;
  position: relative;
  /* grid items: min-width: 0 lets the track shrink below content size,
     so long names / descriptions truncate (via ellipsis on .site-name,
     line-clamp on .site-desc) instead of widening the column. */
  min-width: 0;
}

.otrotl-site-card:hover {
  border-color: var(--otrotl-border-hover);
  box-shadow: var(--otrotl-shadow-card-hover);
  transform: translateY(-0.0625rem);
}

/* --- hidden by filter --- */
.otrotl-site-card.otrotl-hidden {
  display: none;
}

/* --- list-view compact card adjustments --- */
.otrotl-list-view .otrotl-site-card {
  padding: 0.75rem;
  border-radius: 0.5rem;
}

.otrotl-list-view .otrotl-site-icon {
  width: 2rem;
  height: 2rem;
  font-size: 0.875rem;
  border-radius: 0.375rem;
}

.otrotl-list-view .otrotl-site-content {
  flex-direction: row;
  align-items: center;
  gap: 0.75rem;
}

.otrotl-list-view .otrotl-site-name {
  font-size: 0.8125rem;
  margin-bottom: 0;
}

.otrotl-list-view .otrotl-site-desc {
  display: none;
}

.otrotl-list-view .otrotl-site-category {
  display: none;
}

.otrotl-list-view .otrotl-site-actions {
  margin-top: 0;
}

/* ==========================================================================
   Site Icon
   ========================================================================== */

.otrotl-site-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 0.5rem;
  flex-shrink: 0;
  font-size: 1rem;
  transition: transform 0.2s ease;
}

.otrotl-site-card:hover .otrotl-site-icon {
  transform: scale(1.05);
}

/* ==========================================================================
   Site Content (middle section)
   ========================================================================== */

.otrotl-site-content {
  display: flex;
  flex-direction: column;
  flex: 1 1 0;
  min-width: 0;
  /* Hide overflow so a stubborn inline child (e.g. long unbroken URL)
     can't push the flex track wider than its share. */
  overflow: hidden;
}

.otrotl-site-name {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--otrotl-text-primary);
  margin-bottom: 0.125rem;
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.otrotl-site-desc {
  font-size: 0.75rem;
  color: var(--otrotl-text-secondary);
  line-height: 1.4;
  margin-bottom: 0.25rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.otrotl-site-category {
  display: inline-block;
  font-size: 0.625rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--otrotl-text-muted);
  margin-bottom: 0.375rem;
}

/* ==========================================================================
   Site Actions (FAV, SHARE, SAVE)
   ========================================================================== */

.otrotl-site-actions {
  display: flex;
  align-items: center;
  gap: 0.125rem;
  margin-top: 0.375rem;
}

.otrotl-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border: none;
  border-radius: 0.375rem;
  background: transparent;
  color: var(--otrotl-text-muted);
  font-size: 0.75rem;
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease, transform 0.15s ease;
}

.otrotl-action-btn:hover {
  background: var(--otrotl-bg-card-hover);
  transform: scale(1.1);
}

.otrotl-action-btn:focus-visible {
  outline: 0.125rem solid var(--otrotl-accent-strong, #3b82f6);
  outline-offset: 0.0625rem;
}

.otrotl-action-btn:active {
  transform: scale(0.95);
}

/* FAV heart */
.otrotl-action-btn.otrotl-fav-btn:hover {
  color: #f87171;
}

.otrotl-action-btn.otrotl-fav-btn.otrotl-active {
  color: #ef4444;
}

/* SHARE */
.otrotl-action-btn.otrotl-share-btn:hover {
  color: #60a5fa;
}

/* SAVE bookmark */
.otrotl-action-btn.otrotl-save-btn:hover {
  color: #facc15;
}

.otrotl-action-btn.otrotl-save-btn.otrotl-active {
  color: #eab308;
}

/* ==========================================================================
   Site Status (right column: checkbox or registered check)
   ========================================================================== */

.otrotl-site-status {
  display: flex;
  align-items: flex-start;
  flex-shrink: 0;
  padding-top: 0.125rem;
}

/* --- checkbox for unregistered sites --- */
.otrotl-site-checkbox {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.25rem;
  background: transparent;
  cursor: pointer;
  transition: opacity 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
  opacity: 0;
  color: transparent;
  font-size: 0.625rem;
}

.otrotl-site-card:hover .otrotl-site-checkbox {
  opacity: 1;
}

/* keep checkbox visible when checked even without hover
   NOT brand-bridged, deliberately: this blue fill is the ONLY thing that
   distinguishes a "queue for REGISTER" tick from the amber "queue for LOGIN"
   tick below (.otrotl-login-checkbox, #f59e0b). Neither control carries a
   label, so colour is the whole signal — and ~a third of the fleet's brands
   are amber or green, which would collapse the pair. */
.otrotl-site-checkbox.otrotl-checked {
  opacity: 1;
  background: #3b82f6;
  border-color: #3b82f6;
  color: #ffffff;
}

.otrotl-site-checkbox:hover {
  border-color: #3b82f6;
}

.otrotl-site-checkbox:focus-visible {
  outline: 0.125rem solid var(--otrotl-accent-strong, #3b82f6);
  outline-offset: 0.0625rem;
  opacity: 1;
}

/* --- registered green check --- */
.otrotl-site-registered {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.25rem;
  height: 1.25rem;
  color: #22c55e;
  font-size: 0.875rem;
}

/* ==========================================================================
   Panel Footer
   ========================================================================== */

.otrotl-overlay-footer {
  padding: 0.75rem 1rem;
  border-top: 0.0625rem solid var(--otrotl-border);
  background: var(--otrotl-bg-footer);
  flex-shrink: 0;
  /* respect mobile safe-area at the bottom */
  padding-bottom: calc(0.75rem + env(safe-area-inset-bottom, 0rem));
}

.otrotl-register-btn,
.otrotl-login-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0 1rem;
  border: 0.0625rem solid transparent;
  border-radius: 0.5rem;
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, opacity 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
  /* lock height so grid stretch / content differences cannot resize one button */
  height: 2.75rem;
  min-height: 2.75rem;
  max-height: 2.75rem;
  box-sizing: border-box;
  align-self: center;
  white-space: nowrap;
}

.otrotl-register-btn {
  background: var(--site-accent-fill, #2563eb);
  color: var(--site-on-accent, #ffffff);
}

.otrotl-register-btn:hover:not(:disabled) {
  background: var(--site-accent-hover, #1d4ed8);
}

.otrotl-register-btn:active:not(:disabled) {
  transform: scale(0.98);
}

.otrotl-register-btn:focus-visible {
  outline: 0.125rem solid var(--otrotl-accent-strong, #3b82f6);
  outline-offset: 0.125rem;
}

.otrotl-register-btn:disabled,
.otrotl-login-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
}

.otrotl-register-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.375rem;
  border-radius: 0.625rem;
  background: rgba(255, 255, 255, 0.25);
  font-size: 0.6875rem;
  font-weight: 700;
}

/* ==========================================================================
   Toast System
   ========================================================================== */

.otrotl-toast-container {
  position: absolute;
  bottom: 5rem;
  right: 1rem;
  left: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  z-index: var(--otrotl-z-toast);
  pointer-events: none;
}

.otrotl-toast {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.625rem 1rem;
  border-radius: 0.5rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: #ffffff;
  box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.2);
  pointer-events: auto;
  opacity: 0;
  transform: translateY(0.5rem);
  animation: otrotl-toast-in 0.25s ease forwards;
}

.otrotl-toast.otrotl-toast-out {
  animation: otrotl-toast-out 0.2s ease forwards;
}

.otrotl-toast-success {
  background: #16a34a;
}

.otrotl-toast-error {
  background: #dc2626;
}

.otrotl-toast-info {
  background: #2563eb;
}

@keyframes otrotl-toast-in {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes otrotl-toast-out {
  to {
    opacity: 0;
    transform: translateY(0.5rem);
  }
}

/* ==========================================================================
   Card State Borders (unregistered / registered / logged in)

   NOT brand-bridged, deliberately. A card carries exactly one of these three
   classes and the stripe has no label, so the blue/amber/green triad IS the
   status legend. Recolouring only the blue member to the host brand would
   make it indistinguishable from "registered" on an amber-brand host and
   from "logged in" on a green-brand one — and a large share of the fleet's
   accents (#f59e0b, #eab308, #10b981, #16a34a, #14b8a6, #059669, #0d9488)
   sit in exactly those two bands.
   ========================================================================== */

.otrotl-card--unregistered {
  border-left: 0.1875rem solid #3b82f6;
}

.otrotl-card--registered {
  border-left: 0.1875rem solid #f59e0b;
}

.otrotl-card--active {
  border-left: 0.1875rem solid #22c55e;
}

/* ==========================================================================
   Role Selector & Role Badge
   ========================================================================== */

.otrotl-role-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.25rem;
  margin-bottom: 0.25rem;
}

.otrotl-role-select {
  display: block;
  width: 100%;
  max-width: 12rem;
  padding: 0.25rem 0.5rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.375rem;
  background: var(--otrotl-bg-input);
  color: var(--otrotl-text-primary);
  font-size: 0.6875rem;
  line-height: 1.4;
  cursor: pointer;
  min-height: 2.75rem; /* DEV_GUIDE rule 6: touch target >= 2.75rem (Session 7 POLISH-3) */
  transition: border-color 0.15s ease;
}

.otrotl-role-select:focus {
  border-color: var(--otrotl-accent-strong, #3b82f6);
  outline: none;
  box-shadow: 0 0 0 0.125rem var(--site-accent-tint, rgba(59, 130, 246, 0.15));
}

.otrotl-role-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.5rem;
  border-radius: 1rem;
  background: rgba(245, 158, 11, 0.15);
  color: #d97706;
  font-size: 0.625rem;
  font-weight: 600;
  white-space: nowrap;
}

:is(html.dark, html[data-theme="dark"]) .otrotl-role-badge {
  background: rgba(245, 158, 11, 0.2);
  color: #fbbf24;
}

/* ==========================================================================
   Per-Card Action Buttons (Register / Login / Go)
   ========================================================================== */

.otrotl-card-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
  padding: 0.25rem 0.625rem;
  border: 0.0625rem solid transparent;
  border-radius: 0.375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  min-height: 2.75rem; /* DEV_GUIDE rule 6: touch target >= 2.75rem (Session 7 POLISH-3) */
  transition: background-color 0.15s ease, color 0.15s ease, transform 0.15s ease;
}

.otrotl-card-action-btn:active {
  transform: scale(0.95);
}

.otrotl-card-action-btn:focus-visible {
  outline: 0.125rem solid var(--otrotl-accent-strong, #3b82f6);
  outline-offset: 0.0625rem;
}

/* Register (per-card) */
.otrotl-card-register-btn {
  background: rgba(59, 130, 246, 0.1);
  color: #2563eb;
  border-color: rgba(59, 130, 246, 0.2);
}

.otrotl-card-register-btn:hover {
  background: rgba(59, 130, 246, 0.2);
}

:is(html.dark, html[data-theme="dark"]) .otrotl-card-register-btn {
  background: rgba(59, 130, 246, 0.15);
  color: #60a5fa;
}

/* Login (per-card) */
.otrotl-card-login-btn {
  background: rgba(245, 158, 11, 0.1);
  color: #d97706;
  border-color: rgba(245, 158, 11, 0.2);
}

.otrotl-card-login-btn:hover {
  background: rgba(245, 158, 11, 0.2);
}

:is(html.dark, html[data-theme="dark"]) .otrotl-card-login-btn {
  background: rgba(245, 158, 11, 0.15);
  color: #fbbf24;
}

/* Go / Hop (per-card) */
.otrotl-hop-btn {
  background: rgba(34, 197, 94, 0.1);
  color: #16a34a;
  border-color: rgba(34, 197, 94, 0.2);
}

.otrotl-hop-btn:hover {
  background: rgba(34, 197, 94, 0.2);
}

:is(html.dark, html[data-theme="dark"]) .otrotl-hop-btn {
  background: rgba(34, 197, 94, 0.15);
  color: #4ade80;
}

/* ==========================================================================
   Enhanced Footer — Dual Bulk Action Bar

   Layout ladder:
     - Phones ( < 30rem ):  stack — select-all on top, buttons side-by-side row
     - Tablets / desktops:  single row [ select-all | Register | Login ]
     - Smart TVs ( >= 80rem ): larger tap targets and font sizes
   ========================================================================== */

.otrotl-bulk-bar {
  display: grid;
  grid-template-columns: auto 1fr 1fr;
  align-items: center;
  gap: 0.5rem 0.75rem;
}

/* Phone: stack select-all above, buttons share row below */
@media (max-width: 29.9375rem) {
  .otrotl-bulk-bar {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "select select"
      "reg    login";
    gap: 0.625rem;
  }
  .otrotl-bulk-bar .otrotl-select-all { grid-area: select; }
  .otrotl-bulk-bar .otrotl-register-btn { grid-area: reg; }
  .otrotl-bulk-bar .otrotl-login-btn { grid-area: login; }
}

.otrotl-select-all {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8125rem;
  color: var(--otrotl-text-secondary);
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  min-height: 2.75rem;
  padding: 0 0.25rem;
}

.otrotl-select-all input[type="checkbox"] {
  width: 1.125rem;
  height: 1.125rem;
  cursor: pointer;
  accent-color: var(--site-accent-fill, #3b82f6);
  flex-shrink: 0;
}

.otrotl-login-btn {
  background: #d97706;
  color: #ffffff;
}

.otrotl-login-btn:hover:not(:disabled) {
  background: #b45309;
}

.otrotl-login-btn:active:not(:disabled) {
  transform: scale(0.98);
}

.otrotl-login-btn:focus-visible {
  outline: 0.125rem solid #f59e0b;
  outline-offset: 0.125rem;
}

/* Register button inside bulk bar uses grid cell width, not 100% */
.otrotl-bulk-bar .otrotl-register-btn,
.otrotl-bulk-bar .otrotl-login-btn {
  width: 100%;
}

/* ==========================================================================
   Site Status — enhanced for login checkbox + action buttons
   ========================================================================== */

.otrotl-site-status {
  flex-direction: column;
  gap: 0.375rem;
  align-items: center;
}

/* Login checkbox (orange accent) */
.otrotl-login-checkbox {
  border-color: var(--otrotl-border);
}

.otrotl-login-checkbox.otrotl-checked {
  background: #f59e0b;
  border-color: #f59e0b;
  color: #ffffff;
}

.otrotl-login-checkbox:hover {
  border-color: #f59e0b;
}

/* ==========================================================================
   Keyboard-only focus styles (no outline on mouse click)
   ========================================================================== */

.otrotl-overlay-panel *:focus:not(:focus-visible) {
  outline: none;
}

/* ==========================================================================
   Responsive — phones, tablets, desktops, Smart TVs

   Breakpoints (all rem-based, mobile-first):
     < 30rem  → small phones: full-screen panel, actions stack
     < 48rem  → tablets / large phones: checkboxes always visible, tighter chrome
     >= 80rem → Smart TVs / 4K: bigger type, roomier cards, stronger focus rings
   ========================================================================== */

/* --- Phones: full-height sheet, edge-to-edge --- */
@media (max-width: 29.9375rem) {
  :root {
    --otrotl-panel-max-width: 100vw;
    --otrotl-panel-max-height: 85vh;
  }

  .otrotl-overlay-panel {
    border-radius: 0;
    border: 0;
    width: 100vw;
    max-height: 85vh;
    max-height: 85dvh;
  }

  .otrotl-overlay-header {
    padding: 0.75rem 1rem;
  }

  .otrotl-overlay-title {
    font-size: 1rem;
  }

  .otrotl-overlay-body {
    padding: 0.75rem;
  }

  .otrotl-filter-bar {
    padding: 0.625rem 1rem;
    gap: 0.5rem;
  }

  /* Per-card bottom row: icon narrower, status column not stretched */
  .otrotl-site-card {
    padding: 0.75rem;
    gap: 0.625rem;
  }

  /* Touch: make checkboxes visible without hover on mobile */
  .otrotl-site-checkbox {
    opacity: 1;
  }

  /* Role select: full width of content column */
  .otrotl-role-select {
    max-width: 100%;
    font-size: 0.75rem;
  }
}

/* --- Tablets / large phones: keep checkboxes visible (no hover on touch) --- */
@media (hover: none) and (pointer: coarse) {
  .otrotl-site-checkbox {
    opacity: 1;
  }
  .otrotl-site-card:hover {
    transform: none;
  }
}

/* --- Smart TVs / 4K: bigger everything, stronger focus for D-pad ---

   Two activation paths:
     1. Viewport >= 80rem (automatic for large screens)
     2. <html data-tv> or <html data-tv="1"> (manual opt-in for partner sites
        that know they're rendering on a TV — e.g. Roku/Tizen/WebOS wrappers
        where the useragent viewport may not reliably signal TV context).
*/
@media (min-width: 80rem) {
  .otrotl-overlay-title { font-size: 1.375rem; }
  .otrotl-site-name { font-size: 1rem; }
  .otrotl-site-desc { font-size: 0.875rem; }
  .otrotl-site-category { font-size: 0.75rem; }

  .otrotl-card-action-btn {
    font-size: 0.8125rem;
    padding: 0.5rem 1rem;
    min-height: 2.5rem;
  }

  .otrotl-pill {
    font-size: 0.875rem;
    padding: 0.5rem 1rem;
    min-height: 2.5rem;
  }

  .otrotl-search-input {
    font-size: 1rem;
    padding: 0.875rem 2.75rem 0.875rem 2.5rem;
  }

  .otrotl-register-btn,
  .otrotl-login-btn {
    font-size: 1rem;
    height: 3rem;
    min-height: 3rem;
    max-height: 3rem;
    padding: 0 1.25rem;
  }

  /* On TV-scale viewports, bump the minimum card width so cards stay
     legible at 10-foot distance. auto-fill handles the column count. */
  :root {
    --otrotl-card-min-width: 20rem;
    --otrotl-card-min-width-list: 28rem;
  }
}

/* Manual TV mode — mirrors the min-width: 80rem rules so partners can force
   TV-sized chrome even when the viewport doesn't cross the breakpoint. */
html[data-tv] .otrotl-overlay-title { font-size: 1.375rem; }
html[data-tv] .otrotl-site-name { font-size: 1rem; }
html[data-tv] .otrotl-site-desc { font-size: 0.875rem; }
html[data-tv] .otrotl-site-category { font-size: 0.75rem; }

html[data-tv] .otrotl-card-action-btn {
  font-size: 0.8125rem;
  padding: 0.5rem 1rem;
  min-height: 2.5rem;
}

html[data-tv] .otrotl-pill {
  font-size: 0.875rem;
  padding: 0.5rem 1rem;
  min-height: 2.5rem;
}

html[data-tv] .otrotl-search-input {
  font-size: 1rem;
  padding: 0.875rem 2.75rem 0.875rem 2.5rem;
}

html[data-tv] .otrotl-register-btn,
html[data-tv] .otrotl-login-btn {
  font-size: 1rem;
  height: 3rem;
  min-height: 3rem;
  max-height: 3rem;
  padding: 0 1.25rem;
}

html[data-tv] {
  --otrotl-card-min-width: 20rem;
  --otrotl-card-min-width-list: 28rem;
}

/* --- TV / D-pad focus: thicker ring that survives bright backgrounds --- */
@media (min-width: 80rem) {
  .otrotl-view-btn:focus-visible,
  .otrotl-close-btn:focus-visible,
  .otrotl-pill:focus-visible,
  .otrotl-site-checkbox:focus-visible,
  .otrotl-card-action-btn:focus-visible,
  .otrotl-register-btn:focus-visible,
  .otrotl-login-btn:focus-visible,
  .otrotl-action-btn:focus-visible,
  .otrotl-search-input:focus,
  .otrotl-role-select:focus {
    outline: 0.25rem solid var(--otrotl-accent-strong-tv, #60a5fa);
    outline-offset: 0.1875rem;
    box-shadow: 0 0 0 0.375rem var(--site-accent-soft, rgba(96, 165, 250, 0.35));
  }
}

html[data-tv] .otrotl-view-btn:focus-visible,
html[data-tv] .otrotl-close-btn:focus-visible,
html[data-tv] .otrotl-pill:focus-visible,
html[data-tv] .otrotl-site-checkbox:focus-visible,
html[data-tv] .otrotl-card-action-btn:focus-visible,
html[data-tv] .otrotl-register-btn:focus-visible,
html[data-tv] .otrotl-login-btn:focus-visible,
html[data-tv] .otrotl-action-btn:focus-visible,
html[data-tv] .otrotl-search-input:focus,
html[data-tv] .otrotl-role-select:focus {
  outline: 0.25rem solid var(--otrotl-accent-strong-tv, #60a5fa);
  outline-offset: 0.1875rem;
  box-shadow: 0 0 0 0.375rem var(--site-accent-soft, rgba(96, 165, 250, 0.35));
}

/* ==========================================================================
   Reduced motion preference
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .otrotl-overlay-backdrop,
  .otrotl-overlay-panel,
  .otrotl-site-card,
  .otrotl-site-icon,
  .otrotl-action-btn,
  .otrotl-card-action-btn,
  .otrotl-site-checkbox,
  .otrotl-network-trigger,
  .otrotl-register-btn,
  .otrotl-login-btn,
  .otrotl-hop-btn,
  .otrotl-toast,
  .otrotl-detail {
    transition-duration: 0.01s !important;
    animation-duration: 0.01s !important;
  }
}

/* ==========================================================================
   DETAIL VIEW — in-overlay one-page site descriptions
   ==========================================================================
   The detail sub-panel overlays the grid inside the fixed panel. All visuals
   are class-driven (no inline styles) so authored fragments render correctly
   under strict CSP (style-src 'self'). Per-site brand tint comes from
   --otrotl-detail-accent, set ONLY via the data-otrotl-detail-site attribute
   map below — never an inline style.
   ========================================================================== */

/* --- card affordances that open the detail view --- */
.otrotl-detail-trigger {
  cursor: pointer;
}
.otrotl-detail-trigger:focus-visible {
  outline: 0.125rem solid var(--otrotl-trigger-accent, #3b82f6);
  outline-offset: 0.125rem;
  border-radius: 0.375rem;
}
.otrotl-site-icon.otrotl-detail-trigger:hover {
  transform: scale(1.08);
}
.otrotl-site-name.otrotl-detail-trigger:hover {
  color: var(--otrotl-trigger-accent, #3b82f6);
  text-decoration: underline;
  text-underline-offset: 0.15rem;
}
.otrotl-action-btn.otrotl-details-btn:hover {
  color: var(--otrotl-trigger-accent, #3b82f6);
}

/* --- the sub-panel --- */
.otrotl-detail {
  --otrotl-detail-accent: var(--otrotl-trigger-accent, #3b82f6);
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  background: var(--otrotl-bg-panel);
  opacity: 0;
  visibility: hidden;
  transform: translateX(1.5rem);
  transition: opacity 0.25s ease, transform 0.25s ease, visibility 0.25s ease;
}
.otrotl-detail.otrotl-active {
  opacity: 1;
  visibility: visible;
  transform: translateX(0);
}

/* --- sticky back bar --- */
.otrotl-detail-topbar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-shrink: 0;
  padding: 0.75rem 1rem;
  padding-top: calc(0.75rem + env(safe-area-inset-top, 0rem));
  border-bottom: 0.0625rem solid var(--otrotl-border);
  background: var(--otrotl-bg-header);
}
.otrotl-detail-back {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  height: 2.5rem;
  min-height: 2.5rem;
  padding: 0 0.875rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.5rem;
  background: transparent;
  color: var(--otrotl-text-secondary);
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.otrotl-detail-back:hover {
  color: var(--otrotl-text-primary);
  border-color: var(--otrotl-border-hover);
  background: var(--otrotl-bg-card-hover);
}
.otrotl-detail-back:focus-visible {
  outline: 0.125rem solid var(--otrotl-detail-accent);
  outline-offset: 0.125rem;
}
.otrotl-detail-topbar-title {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--otrotl-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- scroll region --- */
.otrotl-detail-scroll {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 1.5rem;
  padding-bottom: calc(1.5rem + env(safe-area-inset-bottom, 0rem));
  scrollbar-width: thin;
  scrollbar-color: var(--otrotl-border) transparent;
}
.otrotl-detail-scroll::-webkit-scrollbar { width: 0.375rem; }
.otrotl-detail-scroll::-webkit-scrollbar-track { background: transparent; }
.otrotl-detail-scroll::-webkit-scrollbar-thumb {
  background: var(--otrotl-border);
  border-radius: 0.1875rem;
}

/* --- authored fragment root --- */
.otrotl-detail-doc {
  max-width: 56rem;
  margin: 0 auto;
  color: var(--otrotl-text-primary);
}

/* --- hero --- */
.otrotl-detail-hero {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
  padding: 1.5rem;
  border-radius: 1rem;
  background: var(--otrotl-bg-card-hover);
  background: linear-gradient(135deg,
    color-mix(in srgb, var(--otrotl-detail-accent) 16%, transparent),
    color-mix(in srgb, var(--otrotl-detail-accent) 4%, transparent));
  border: 0.0625rem solid var(--otrotl-border);
  border-color: color-mix(in srgb, var(--otrotl-detail-accent) 25%, var(--otrotl-border));
}
.otrotl-detail-hero-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 4rem;
  height: 4rem;
  flex-shrink: 0;
  border-radius: 1rem;
  font-size: 1.75rem;
  color: #ffffff;
  background: var(--otrotl-detail-accent);
}
.otrotl-detail-hero-text { min-width: 0; }
.otrotl-detail-eyebrow {
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--otrotl-detail-accent);
  margin-bottom: 0.25rem;
}
.otrotl-detail-title {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1.15;
  color: var(--otrotl-text-primary);
}
.otrotl-detail-domain {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 0.5rem;
  font-size: 0.8125rem;
  color: var(--otrotl-text-secondary);
  text-decoration: none;
}
.otrotl-detail-domain:hover { color: var(--otrotl-detail-accent); }

/* --- lede --- */
.otrotl-detail-lede {
  margin: 0 0 1.5rem;
  font-size: 1.0625rem;
  line-height: 1.6;
  color: var(--otrotl-text-secondary);
}

/* --- generic section --- */
.otrotl-detail-section { margin: 0 0 1.75rem; }
.otrotl-detail-section-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.75rem;
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--otrotl-text-muted);
}
.otrotl-detail-section-title::before {
  content: "";
  width: 0.75rem;
  height: 0.125rem;
  border-radius: 1rem;
  background: var(--otrotl-detail-accent);
}
.otrotl-detail-section p {
  margin: 0 0 0.75rem;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--otrotl-text-secondary);
}
.otrotl-detail-section p:last-child { margin-bottom: 0; }

/* --- feature grid --- */
.otrotl-detail-features {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0.75rem;
}
.otrotl-detail-feature {
  display: flex;
  gap: 0.75rem;
  padding: 1rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.75rem;
  background: var(--otrotl-bg-card);
}
.otrotl-detail-feature-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  flex-shrink: 0;
  border-radius: 0.5rem;
  font-size: 1rem;
  color: var(--otrotl-detail-accent);
  background: color-mix(in srgb, var(--otrotl-detail-accent) 14%, transparent);
}
.otrotl-detail-feature-body { min-width: 0; }
.otrotl-detail-feature-title {
  margin: 0 0 0.25rem;
  font-size: 0.875rem;
  font-weight: 700;
  color: var(--otrotl-text-primary);
}
.otrotl-detail-feature-text {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--otrotl-text-secondary);
}

/* --- checklist (who it's for / benefits) --- */
.otrotl-detail-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.otrotl-detail-list li {
  position: relative;
  padding-left: 1.5rem;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--otrotl-text-secondary);
}
.otrotl-detail-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--otrotl-detail-accent);
}

/* --- highlight stats --- */
.otrotl-detail-highlights {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: 0.75rem;
}
.otrotl-detail-stat {
  padding: 1rem;
  text-align: center;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.75rem;
  background: var(--otrotl-bg-card);
}
.otrotl-detail-stat-value {
  font-size: 1.5rem;
  font-weight: 800;
  line-height: 1.1;
  color: var(--otrotl-detail-accent);
}
.otrotl-detail-stat-label {
  margin-top: 0.25rem;
  font-size: 0.75rem;
  color: var(--otrotl-text-muted);
}

/* --- visual / screenshot slot --- */
.otrotl-detail-visual {
  margin: 0 0 1.75rem;
  border: 0.0625rem solid var(--otrotl-border);
  border-radius: 0.75rem;
  overflow: hidden;
  background: var(--otrotl-bg-card-hover);
}
.otrotl-detail-visual img { display: block; width: 100%; height: auto; }
.otrotl-detail-visual--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 10rem;
  color: var(--otrotl-text-muted);
  font-size: 0.875rem;
}

/* --- CTAs --- */
.otrotl-detail-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.5rem;
}
.otrotl-detail-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: 2.875rem;
  min-height: 2.875rem;
  padding: 0 1.25rem;
  border: 0.0625rem solid transparent;
  border-radius: 0.625rem;
  font-size: 0.9375rem;
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  background: var(--otrotl-detail-accent);
  color: #ffffff;
  transition: filter 0.15s ease, transform 0.15s ease;
}
.otrotl-detail-cta-btn:hover { filter: brightness(1.08); }
.otrotl-detail-cta-btn:active { transform: scale(0.98); }
.otrotl-detail-cta-btn:focus-visible {
  outline: 0.125rem solid var(--otrotl-detail-accent);
  outline-offset: 0.1875rem;
}
.otrotl-detail-cta-btn--secondary {
  background: transparent;
  color: var(--otrotl-detail-accent);
  border-color: color-mix(in srgb, var(--otrotl-detail-accent) 40%, var(--otrotl-border));
}

/* --- fallback / coming-soon note --- */
.otrotl-detail-note {
  margin: 0.5rem 0 1.25rem;
  font-size: 0.875rem;
  font-style: italic;
  color: var(--otrotl-text-muted);
}

/* --- phones --- */
@media (max-width: 29.9375rem) {
  .otrotl-detail-scroll { padding: 1rem; }
  .otrotl-detail-hero {
    flex-direction: column;
    align-items: flex-start;
    padding: 1.25rem;
  }
  .otrotl-detail-title { font-size: 1.25rem; }
  .otrotl-detail-lede { font-size: 1rem; }
}

/* --- Smart TV / 4K scale-up --- */
@media (min-width: 80rem) {
  .otrotl-detail-title { font-size: 1.875rem; }
  .otrotl-detail-lede { font-size: 1.25rem; }
  .otrotl-detail-section p,
  .otrotl-detail-list li { font-size: 1.0625rem; }
  .otrotl-detail-cta-btn { height: 3.25rem; min-height: 3.25rem; font-size: 1.0625rem; }
}

/* ==========================================================================
   Per-site accent map — keyed by the live network_sites.site_code (UPPERCASE).
   Values are the canonical DEV_GUIDE §8 brand accents. Note codes that differ
   from the repo dir name: vtradeevents.com => TRADESHOWS; HINDU-TEMPLES keeps
   its hyphen. Unmapped/future sites fall back to the default accent above.
   ========================================================================== */
.otrotl-detail[data-otrotl-detail-site="ONETIMELOGIN"]   { --otrotl-detail-accent: #8b5cf6; }
.otrotl-detail[data-otrotl-detail-site="INDIANSHOPPING"] { --otrotl-detail-accent: #f97316; }
.otrotl-detail[data-otrotl-detail-site="MAILMOOLAH"]     { --otrotl-detail-accent: #8b5cf6; }
.otrotl-detail[data-otrotl-detail-site="TUBERAKER"]      { --otrotl-detail-accent: #8b5cf6; }
.otrotl-detail[data-otrotl-detail-site="CHICKENTANDY"]   { --otrotl-detail-accent: #dc2626; }
.otrotl-detail[data-otrotl-detail-site="TRADESHOWS"]     { --otrotl-detail-accent: #6366f1; }
.otrotl-detail[data-otrotl-detail-site="CYBERSECCLOUD"]  { --otrotl-detail-accent: #06b6d4; }
.otrotl-detail[data-otrotl-detail-site="CBSEAITUTOR"]    { --otrotl-detail-accent: #f59e0b; }
.otrotl-detail[data-otrotl-detail-site="SOLVUH"]         { --otrotl-detail-accent: #eab308; }
.otrotl-detail[data-otrotl-detail-site="EASYMEALZ"]      { --otrotl-detail-accent: #10b981; }
.otrotl-detail[data-otrotl-detail-site="INDIANMARRIAGE"] { --otrotl-detail-accent: #ec4899; }
.otrotl-detail[data-otrotl-detail-site="EDUNET"]         { --otrotl-detail-accent: #8b5cf6; }
.otrotl-detail[data-otrotl-detail-site="NOIDNURSE"]      { --otrotl-detail-accent: #ec4899; }
.otrotl-detail[data-otrotl-detail-site="AICHUMS"]        { --otrotl-detail-accent: #3b82f6; }
.otrotl-detail[data-otrotl-detail-site="NOIDNOGGIN"]     { --otrotl-detail-accent: #a855f7; }
.otrotl-detail[data-otrotl-detail-site="HINDU-TEMPLES"]  { --otrotl-detail-accent: #f97316; }
.otrotl-detail[data-otrotl-detail-site="PRODUCTPALS"]    { --otrotl-detail-accent: #f97316; }
.otrotl-detail[data-otrotl-detail-site="RETIREPLUSPLUS"] { --otrotl-detail-accent: #f59e0b; }
.otrotl-detail[data-otrotl-detail-site="VIRTUALMALLS"]   { --otrotl-detail-accent: #6366f1; }
.otrotl-detail[data-otrotl-detail-site="HEALTHHAVEN"]    { --otrotl-detail-accent: #14b8a6; }
.otrotl-detail[data-otrotl-detail-site="BIZWITHAFRICA"]  { --otrotl-detail-accent: #16a34a; }
.otrotl-detail[data-otrotl-detail-site="SHAREFAM"]       { --otrotl-detail-accent: #0d9488; }
.otrotl-detail[data-otrotl-detail-site="PEQUITY"]        { --otrotl-detail-accent: #6366f1; }
.otrotl-detail[data-otrotl-detail-site="TRUSTS"]         { --otrotl-detail-accent: #059669; }
