/* ============================================================
   shared/components/dashboard.css — Blue Chips primitives.
   Re-locked 2026-04-30 (CLAUDE.md): monochromatic cyan accent.
   Sync'd to app/public/shared-dashboard.css via shared/sync.sh.
   Consumers: any page that wants Bento + glass card primitives.

   USAGE
     <link rel="stylesheet" href="/shared-dashboard.css">
     <div class="ro-bento">
       <div class="ro-card ro-card--span-2 ro-card--glass">…</div>
       <div class="ro-card ro-card--glass">…</div>
       …
     </div>

   The classes are namespaced with `ro-` so they don't collide with
   page-local component classes (rch-, hh-, ck-sb-, etc.). New
   surfaces should reach for these before rolling their own.
   ============================================================ */

/* ---- Tokens (mirrors shared.css; isolated here so this file is
   loadable standalone for Storybook / preview pages).
   ----
   2026-05-01: Blue Chips Mono palette. Two cyan tokens — `--ro-cyan`
   (#00FFFF) for primary accent surfaces, `--ro-cyan-deep` (#008FA8)
   for darker companion contexts (borders, muted hovers). ---- */
:root {
  --ro-card-bg-dark:        rgba(255, 255, 255, 0.03);
  --ro-card-bg-light:       rgba(255, 255, 255, 0.85);
  --ro-card-border-dark:    rgba(255, 255, 255, 0.10);
  --ro-card-border-light:   rgba(14, 31, 38, 0.10);
  --ro-card-radius:         24px;
  --ro-card-radius-sm:      14px;
  --ro-card-blur:           10px;
  --ro-cyan:                #00FFFF;
  --ro-cyan-deep:           #008FA8;
  --ro-shadow-glass:        0 1px 0 rgba(255,255,255,0.05) inset, 0 4px 18px rgba(0,0,0,0.18), 0 18px 48px rgba(0,0,0,0.30);
  --ro-shadow-glass-light:  0 1px 0 rgba(255,255,255,0.65) inset, 0 4px 12px rgba(14,31,38,0.06), 0 18px 48px rgba(14,31,38,0.10);
}

/* ============================================================
   Bento grid — modular, varying-size cards.
   The grid uses a 12-column track at >=1024px so cards can claim
   span-1..6 cells; collapses to 6 columns on tablets and 1 on
   phones. Card-level span classes (`ro-card--span-N`) opt cards
   into wider cells without the consumer having to know the column
   count.
   ============================================================ */
.ro-bento {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 16px;
  align-items: stretch;
}
@media (max-width: 1024px) {
  .ro-bento { grid-template-columns: repeat(6, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
  .ro-bento { grid-template-columns: 1fr; gap: 12px; }
}

.ro-card { grid-column: span 4; }                /* default — three across at desktop */
.ro-card--span-2 { grid-column: span 2; }        /* tight stat cell */
.ro-card--span-3 { grid-column: span 3; }
.ro-card--span-4 { grid-column: span 4; }
.ro-card--span-6 { grid-column: span 6; }
.ro-card--span-8 { grid-column: span 8; }
.ro-card--span-12,
.ro-card--full   { grid-column: 1 / -1; }
@media (max-width: 1024px) {
  .ro-card,
  .ro-card--span-3,
  .ro-card--span-4 { grid-column: span 3; }
  .ro-card--span-6,
  .ro-card--span-8 { grid-column: span 6; }
}
@media (max-width: 640px) {
  .ro-card,
  .ro-card--span-2,
  .ro-card--span-3,
  .ro-card--span-4,
  .ro-card--span-6,
  .ro-card--span-8 { grid-column: span 1; }
}

/* Tall variants — for stories / sidebars / charts that want vertical
   real estate. Pair with `.ro-card--span-N` for full bento control. */
.ro-card--tall   { grid-row: span 2; }
.ro-card--xtall  { grid-row: span 3; }

/* ============================================================
   Glass card — soft glassmorphism on the Blue Chips dark surface.
   Per the locked spec:
     bg     rgba(255,255,255,0.03)
     border 1px solid rgba(255,255,255,0.10)
     radius 24px
     blur   10px
   The card blur stays at 10px (the heavier 24px blur is reserved
   for the sidebar rail). Light theme uses a brighter background
   for legibility; the structural numbers (radius, blur, border-
   width) stay constant across themes.
   ============================================================ */
.ro-card--glass {
  position: relative;
  padding: 22px 24px;
  border-radius: var(--ro-card-radius);
  background: var(--ro-card-bg-dark);
  border: 1px solid var(--ro-card-border-dark);
  backdrop-filter: blur(var(--ro-card-blur)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--ro-card-blur)) saturate(140%);
  box-shadow: var(--ro-shadow-glass);
  color: inherit;
  isolation: isolate;
  overflow: hidden;
}
:root[data-theme="light"] .ro-card--glass,
[data-theme="light"] .ro-card--glass {
  background: var(--ro-card-bg-light);
  border-color: var(--ro-card-border-light);
  box-shadow: var(--ro-shadow-glass-light);
}

/* Subtle internal highlight — a faint diagonal sheen anchored to
   the top edge so the card reads as glass, not flat opacity. */
.ro-card--glass::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  background: linear-gradient(
    160deg,
    rgba(255, 255, 255, 0.06) 0%,
    rgba(255, 255, 255, 0) 28%
  );
  z-index: 0;
}
[data-theme="light"] .ro-card--glass::before {
  background: linear-gradient(
    160deg,
    rgba(255, 255, 255, 0.45) 0%,
    rgba(255, 255, 255, 0) 30%
  );
}
.ro-card--glass > * { position: relative; z-index: 1; }

/* Hover lift — lightweight, no heavy shadow shift so it feels like
   the card is responsive but doesn't jump out of the bento grid. */
.ro-card--glass.ro-card--hover:hover,
a.ro-card--glass:hover {
  border-color: color-mix(in srgb, var(--ro-cyan) 30%, var(--ro-card-border-dark));
  transform: translateY(-1px);
  transition: transform .15s ease, border-color .15s ease;
}

/* ============================================================
   Card-internal layout helpers. Keeps page-level CSS thin:
   the eyebrow + big number + sparkline + sub-line is the
   canonical Blue-Chips card composition.
   ============================================================ */
.ro-card-eyebrow {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: color-mix(in srgb, currentColor 60%, transparent);
  margin: 0 0 12px;
}
.ro-card-num {
  font-size: 32px;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  margin: 0;
}
.ro-card-num--lg { font-size: 40px; }
.ro-card-num--sm { font-size: 22px; }
.ro-card-num-sub {
  font-size: 0.45em;
  font-weight: 600;
  color: color-mix(in srgb, currentColor 55%, transparent);
  margin-left: 6px;
  letter-spacing: 0;
  text-transform: none;
}
.ro-card-sub {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: color-mix(in srgb, currentColor 70%, transparent);
}

/* ============================================================
   Stats row — for big-number rows that live OUTSIDE the bento
   grid (e.g. Reach's tile row on Search Console). Same tabular-
   nums + Inter weight discipline so numbers across surfaces
   visually align.
   ============================================================ */
.ro-stat-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" on, "lnum" on;
  letter-spacing: -0.02em;
}

/* ============================================================
   Reduced motion — disable hover lift if the user opts out.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .ro-card--glass.ro-card--hover:hover,
  a.ro-card--glass:hover {
    transform: none;
    transition: none;
  }
}

/* ============================================================
   .ro-layout — Primary Layout Container (locked invariant 2026-05-01).
   The sidebar is the persistent left rail; .ro-main-content is the
   swap surface where feature content (Radar / Newsroom / Diagnostics)
   is injected by shared-router.js without document reload.

   Pages opt into the shell by structuring their <body> as:

     <body class="page-X">
       <div class="ro-layout">
         <div class="ro-layout-sidebar">
           <div id="sidebarMount"></div>
         </div>
         <main class="ro-main-content">
           <!-- page-specific content; this <main> is what the
                router replaces on sidebar navigation -->
         </main>
       </div>
     </body>

   shared-router.js intercepts sidebar <a> clicks, fetches the
   destination, extracts its <main class="ro-main-content"> + inline
   page styles + page-local scripts, and swaps them in. The sidebar
   itself is never re-mounted on navigation — only the active-state
   inference re-runs against the new pathname.
   ============================================================ */
.ro-layout {
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr);
  min-height: 100vh;
  align-items: stretch;
}

.ro-layout-sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
  z-index: 90;
}

.ro-main-content {
  position: relative;
  min-width: 0;       /* needed so the main column can shrink under content overflow */
  min-height: 100vh;
}

/* When the sidebar component lives inside the layout shell, it fills
   the sticky column instead of being position-fixed. Override the
   default fixed-positioning rule from shared-sidebar.css so the rail
   participates in the layout grid. Pages NOT using the layout shell
   keep the legacy fixed positioning untouched. */
.ro-layout-sidebar .ck-sidebar,
.ro-layout-sidebar .sidebar {
  position: relative;
  top: auto; left: auto; bottom: auto;
  width: 100%;
  /* 100vh, not 100%. The #sidebarMount div between .ro-layout-sidebar
     and .ck-sidebar has no explicit height, so `height: 100%` cascades
     to content-height and the rail collapses. 100vh reaches the
     viewport directly so the bottom stack (Otto's quarter, identity,
     utility footer) pins correctly. */
  height: 100vh;
  display: flex;
  z-index: auto;
}

/* Neutralize the legacy `margin-left: 260px` on per-page content wraps
   when the page lives inside the layout shell. The .ro-layout grid
   handles column spacing now, so the manual offset would push content
   right by an additional 260px and overflow the viewport. Pages outside
   .ro-layout still apply their own offset rule. */
.ro-layout .home-content-wrap,
.ro-layout .rch-content-wrap,
.ro-layout .pg-wrap,
.ro-layout .wrap,
.ro-layout .al-content-wrap,
.ro-layout .pd-content-wrap,
.ro-layout .set-content-wrap,
.ro-layout .cs-content-wrap,
.ro-layout .dash-content {
  margin-left: 0 !important;
}

/* Mobile collapse — under 768px the sidebar tucks behind a hamburger
   toggle. The layout collapses to a single column so the main content
   fills width; consuming pages set .force-show on the inner <aside>
   to slide it in. */
@media (max-width: 768px) {
  .ro-layout {
    grid-template-columns: 1fr;
  }
  .ro-layout-sidebar {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: 260px;
    height: 100vh;
    z-index: 110;
    display: none;
  }
  .ro-layout-sidebar.is-open {
    display: block;
  }
}

/* View transitions — when the router uses document.startViewTransition
   to swap .ro-main-content, the sidebar stays mounted and the main
   crossfades. Naming the main + sidebar nodes lets the browser morph
   them independently in supporting browsers. */
.ro-layout-sidebar { view-transition-name: ro-layout-sidebar; }
.ro-main-content   { view-transition-name: ro-main-content; }
::view-transition-old(ro-main-content),
::view-transition-new(ro-main-content){
  animation-duration: .28s;
  animation-timing-function: cubic-bezier(.2, .7, .2, 1);
}
::view-transition-old(ro-layout-sidebar),
::view-transition-new(ro-layout-sidebar){
  animation-duration: .2s;
}
