/* ────────────────────────────────────────────────────────────────────
 *  URAI · Desk Drawer nav — concept overlay
 *
 *  Replaces the existing left-side .side-menu with a horizontal
 *  drawer that pulls DOWN from the top of the viewport, exactly per
 *  the v3-desk.jsx concept (Claude design canvas → URAI Tutor (1).zip).
 *
 *  Visual rules carried over from the source:
 *    Palette
 *      wood       #2D1A0C   primary ink, drawer trim
 *      coral      #C66E5A   Review accent
 *      butter     #C89858   Study accent
 *      sage       #6E8E6A   Library accent
 *      cream-1    #EFE6CF   drawer body bg (default tint)
 *      cream-2    #F6EFDC   active compartment / brand chip
 *      cream-3    #EBE1C4   You compartment tint
 *      cream-4    #F0E8CE   Library compartment tint
 *    Typography
 *      Fraunces (italic, 22 for stat numbers, 17 for card names)
 *      DM Mono (uppercase eyebrows, meta lines)
 *  ──────────────────────────────────────────────────────────────────── */

@import url('https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,500;0,9..144,600;0,9..144,700;1,9..144,400;1,9..144,500;1,9..144,600&family=DM+Mono:wght@400;500&display=swap');

/* The desk-* tokens are aliases of the main app palette so the
 * drawer inherits whatever cosy theme is currently active (light,
 * dark, etc.). The original `#2D1A0C` walnut / `#C66E5A` coral
 * etc. came from the standalone design canvas; here we just point
 * them at the actual --ink / --primary / --accent system from
 * styles.css so the desk reads as "part of URAI" instead of a
 * grafted concept. */
body.desk-concept {
  /* Wood frame + ink == warm forest charcoal */
  --desk-wood:    var(--ink, #1f2a25);

  /* Compartment accents (the swatches + icon strokes + per-card
   * highlight) — pull from the existing accent system:
   *   Study   → warm butter (a tint of accent)
   *   Review  → terracotta accent itself
   *   Library → primary sage green
   *   You     → ink (kept dark; "personal" feels grounded) */
  --desk-coral:   var(--accent, #c97a4a);
  --desk-sage:    var(--primary, #3d6b56);
  --desk-butter:  #c9a14a;
  --desk-you:     var(--ink, #1f2a25);

  /* Compartment backgrounds — derive from the cosy cream family.
   * One tint per group so they read as different "drawers within
   * a drawer" without competing with the surface gradient. */
  --desk-cream-1: var(--surface-subtle, #f5f0e6);
  --desk-cream-2: var(--surface, #fffdf7);
  --desk-cream-3: var(--surface-muted, #ebe3d2);
  --desk-cream-4: var(--accent-soft, #f8e9dc);

  /* Ink at various alphas — used for dividers, secondary text, etc.
   * Anchored on --ink so dark-mode flips them automatically when
   * the user switches theme. */
  --desk-ink-55:  color-mix(in srgb, var(--ink, #1f2a25) 60%, transparent);
  --desk-ink-18:  color-mix(in srgb, var(--ink, #1f2a25) 18%, transparent);
  --desk-ink-25:  color-mix(in srgb, var(--ink, #1f2a25) 25%, transparent);
}

/* ── Hide the prod sidebar entirely when desk concept is on. The
 * new drawer is rendered in its own root (#desk-drawer-root) and
 * the original .menu-backdrop stays unused. */
body.desk-concept .side-menu,
body.desk-concept .menu-backdrop {
  display: none !important;
}

/* ── Drawer root + open/close state.
 * Lives at the very top of the viewport and translates DOWN. The
 * .is-open class is toggled by desk-nav.js when the user hits the
 * existing #menu-toggle button. */
.desk-drawer-root {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1000;
  font-family: 'DM Mono', ui-monospace, monospace;
  color: var(--desk-wood);
  pointer-events: none;
}
.desk-drawer-root.is-open { pointer-events: auto; }

/* Dark scrim behind the drawer (covers the rest of the app while
 * open). Fades in/out independently of the drawer slide. */
.desk-drawer-scrim {
  position: fixed;
  inset: 0;
  background: color-mix(in srgb, var(--ink, #1f2a25) 32%, transparent);
  opacity: 0;
  transition: opacity 320ms ease;
  pointer-events: none;
  z-index: 0;
}
.desk-drawer-root.is-open .desk-drawer-scrim {
  opacity: 1;
  pointer-events: auto;
}

/* The drawer body. Slides down from above the viewport. Uses a
 * gentle back ease-out — overshoots by only ~2% past its stop
 * (was ~7% which read as "the drawer keeps going"). Feels like a
 * solid drawer hitting its rail rather than a rubbery bounce. */
.desk-drawer {
  position: relative;
  background: var(--desk-cream-1);
  border-bottom: 1px solid var(--desk-wood);
  box-shadow: 0 24px 60px color-mix(in srgb, var(--ink, #1f2a25) 25%, transparent);
  transform: translateY(-100%);
  transition: transform 480ms cubic-bezier(0.32, 1.18, 0.55, 1);
  will-change: transform;
  padding-top: 12px;
}
.desk-drawer-root.is-open .desk-drawer {
  transform: translateY(0);
}
/* Faster, no-overshoot close — matches "pushing the drawer shut" */
.desk-drawer-root:not(.is-open) .desk-drawer {
  transition: transform 320ms cubic-bezier(0.55, 0, 0.78, 0.22);
}

/* ── Header strip ── */
.desk-drawer-head {
  padding: 14px 32px 16px;
  display: flex;
  align-items: center;
  gap: 24px;
  border-bottom: 1px solid var(--desk-ink-25);
}
.desk-drawer-brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Fraunces', Georgia, serif;
  font-style: italic;
  font-size: 19px;
  color: var(--desk-wood);
  letter-spacing: -0.005em;
}
.desk-drawer-brand::before {
  content: '';
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--desk-coral);
  display: inline-block;
  transform: translateY(-1px);
}
.desk-drawer-eyebrow {
  font-size: 9.5px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--desk-ink-55);
}
.desk-drawer-spacer { flex: 1; }

.desk-drawer-stats {
  display: flex;
  align-items: baseline;
  gap: 16px;
}
.desk-drawer-stats .label {
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--desk-ink-55);
}
.desk-drawer-stats .value {
  font-family: 'Fraunces', Georgia, serif;
  font-style: italic;
  font-size: 22px;
  color: var(--desk-wood);
}
.desk-drawer-stats .value.is-coral { color: var(--desk-coral); }
.desk-drawer-stats .divider {
  width: 1px;
  height: 18px;
  background: var(--desk-ink-25);
  display: inline-block;
}
.desk-drawer-userchip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 10px;
  border: 1px solid var(--desk-wood);
  border-radius: 0;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--desk-wood);
  background: transparent;
  cursor: pointer;
}
.desk-drawer-userchip-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--desk-butter);
  color: var(--desk-cream-2);
  font-family: 'Fraunces', Georgia, serif;
  font-style: italic;
  display: grid;
  place-items: center;
  font-size: 11px;
}

/* ── 4-compartment grid ── */
.desk-drawer-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
}
.desk-comp {
  padding: 20px 22px 24px;
  position: relative;
  /* No forced min-height — let each column be as tall as its content.
   * The CSS grid rows auto-stretch to match the tallest column (Study,
   * with 13 items) so nothing looks empty or unintentionally vacant. */
  border-right: 1px solid var(--desk-ink-25);
}
.desk-comp:last-child { border-right: 0; }
/* Compartment surfaces — one tint per prod section so the four
 * groups feel distinct without breaking the warmth of the app.
 * Group ids match the production side-menu sections 1:1:
 *   main     → lightest cream    (start here)
 *   study    → soft cream        (the bulk of the work, neutral)
 *   progress → terracotta-tinted (review = the warm accent)
 *   account  → warmer muted      (settings, profile) */
.desk-comp[data-group="main"]     { background: var(--desk-cream-2); }
.desk-comp[data-group="study"]    { background: var(--desk-cream-1); }
.desk-comp[data-group="progress"] { background: var(--desk-cream-4); }
.desk-comp[data-group="account"]  { background: var(--desk-cream-3); }

/* Compartment header */
.desk-comp-tab {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}
.desk-comp-tab .swatch {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.desk-comp[data-group="main"]     .desk-comp-tab .swatch { background: var(--desk-butter); }
.desk-comp[data-group="study"]    .desk-comp-tab .swatch { background: var(--desk-sage);   }
.desk-comp[data-group="progress"] .desk-comp-tab .swatch { background: var(--desk-coral);  }
.desk-comp[data-group="account"]  .desk-comp-tab .swatch { background: var(--desk-you);    }
.desk-comp-tab .label {
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--desk-wood);
  font-family: 'DM Mono', monospace;
}
.desk-comp-sub {
  font-family: 'Fraunces', Georgia, serif;
  font-style: italic;
  font-size: 13px;
  /* Use ink at 68% so the subtitle is legible on any of the four
   * compartment cream tints without being as bold as the label. */
  color: color-mix(in srgb, var(--ink, #1f2a25) 68%, transparent);
  margin: 0 0 14px;
}

/* Cards.
 * Now that compartments mirror the production side-menu (and the
 * Study tools column has 13 items), the card column has its own
 * vertical scroll so the drawer body stays at a sane height. Other
 * compartments still fit without scrolling. */
.desk-comp-cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* Cap the card stack a little under the viewport so the wooden
   * pull strip stays visible below. min(420px, ...) keeps short
   * compartments from forcing a scrollbar. */
  max-height: min(60vh, 540px);
  overflow-y: auto;
  /* Subtle scrollbar styling that fits the warm theme */
  scrollbar-width: thin;
  scrollbar-color: var(--desk-ink-25) transparent;
  /* Give a touch of right-padding so cards don't kiss the scrollbar */
  padding-right: 6px;
}
.desk-comp-cards::-webkit-scrollbar { width: 6px; }
.desk-comp-cards::-webkit-scrollbar-thumb {
  background: var(--desk-ink-25);
  border-radius: 999px;
}
.desk-comp-cards::-webkit-scrollbar-track { background: transparent; }
.desk-card {
  position: relative;
  padding: 12px 12px 12px 14px;
  /* Solid-enough card so it clearly reads against the cream compartment
   * background (cream-1 is #f5f0e6 — rgba white at 40% blends in).
   * 85% keeps a faint warm undertone from the compartment colour while
   * giving the card clear visual presence. */
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid var(--desk-ink-25);
  box-shadow: 2px 3px 0 color-mix(in srgb, var(--ink, #1f2a25) 10%, transparent),
              0 1px 0 rgba(255,255,255,0.9) inset;
  /* CRITICAL: do not flex-shrink. The Study column has 13 cards inside
   * a `.desk-comp-cards` container with max-height: 540px and
   * flex-direction: column. Default `flex-shrink: 1` lets the cards
   * compress to fit, which clips the meta line and makes them visually
   * overlap. flex-shrink:0 keeps each card at its natural height and
   * lets the container scroll instead. */
  flex: 0 0 auto;
  transition: transform 160ms, background 160ms, border-color 160ms, box-shadow 160ms;
  cursor: pointer;
  text-align: left;
  color: var(--desk-wood);
  display: grid;
  grid-template-columns: 28px 1fr;
  gap: 10px;
  align-items: center;
  font-family: 'DM Mono', monospace;
  border-radius: 0;
  /* Cards live INSIDE the drawer DOM, so they automatically inherit
   * the drawer's translateY animation — when the drawer slides down,
   * the cards ride along. We don't fade or pop them in independently;
   * they're carried by the drawer as physical objects would be.
   *
   * Their only own transform is the small resting rotation that
   * makes the contents look "casually placed". */
  opacity: 1;
  transform: rotate(var(--desk-card-rest, 0deg));
}
/* Resting rotation jitter — every 3rd card a different small angle
 * so the four columns don't read as a perfect grid. */
.desk-card:nth-child(3n)      { --desk-card-rest: -0.5deg; }
.desk-card:nth-child(3n + 1)  { --desk-card-rest:  0deg;   }
.desk-card:nth-child(3n + 2)  { --desk-card-rest:  0.5deg; }

/* ── Inertia jiggle ──
 * The drawer slides down with overshoot in 540ms; around the 50%
 * mark it has decelerated to its stop and bounces back. At that
 * moment a real card inside would CONTINUE moving down for a
 * fraction of a second (Newton's first law) before friction +
 * the bottom of the drawer arrest it. We model that with a small
 * per-card translateY oscillation — 0 → +8px (inertia carries it
 * down) → -2px (bounce back) → 0 (settled).
 *
 * The animation only starts at ~260ms (matching the drawer's
 * peak-deceleration moment), and per-card stagger is small so the
 * whole row feels like one object's contents settling, not a
 * cascading marketing animation. */
.desk-drawer-root.is-open .desk-card {
  animation: desk-card-inertia 420ms cubic-bezier(0.32, 1.18, 0.55, 1) both;
  animation-delay: calc(220ms + var(--desk-row-delay, 0ms) + var(--desk-col-delay, 0ms));
}
@keyframes desk-card-inertia {
  0% {
    transform: translateY(0) rotate(var(--desk-card-rest, 0deg));
  }
  40% {
    /* Inertia: card continues downward briefly as drawer decelerates.
     * Was 8px; trimmed to 4px so cards just nudge rather than jump. */
    transform: translateY(4px) rotate(var(--desk-card-rest, 0deg));
  }
  70% {
    /* Friction catches it; small rebound back up. */
    transform: translateY(-1px) rotate(var(--desk-card-rest, 0deg));
  }
  100% {
    transform: translateY(0) rotate(var(--desk-card-rest, 0deg));
  }
}
/* Small per-column AND per-row delay variation simulates slight
 * differences in friction / mass between cards. Kept tight (≤120ms
 * total) so the row feels coherent, not staggered. */
.desk-comp[data-group="main"]     { --desk-col-delay:  0ms; }
.desk-comp[data-group="study"]    { --desk-col-delay: 20ms; }
.desk-comp[data-group="progress"] { --desk-col-delay: 40ms; }
.desk-comp[data-group="account"]  { --desk-col-delay: 60ms; }
.desk-card:nth-child(1)  { --desk-row-delay:   0ms; }
.desk-card:nth-child(2)  { --desk-row-delay:  12ms; }
.desk-card:nth-child(3)  { --desk-row-delay:  24ms; }
.desk-card:nth-child(4)  { --desk-row-delay:  36ms; }
.desk-card:nth-child(5)  { --desk-row-delay:  48ms; }
.desk-card:nth-child(6)  { --desk-row-delay:  60ms; }
.desk-card:nth-child(7)  { --desk-row-delay:  72ms; }
.desk-card:nth-child(8)  { --desk-row-delay:  84ms; }
.desk-card:nth-child(9)  { --desk-row-delay:  96ms; }
.desk-card:nth-child(10) { --desk-row-delay: 108ms; }
.desk-card:nth-child(11) { --desk-row-delay: 120ms; }
.desk-card:nth-child(12) { --desk-row-delay: 132ms; }
.desk-card:nth-child(13) { --desk-row-delay: 144ms; }

/* When closing: kill the inertia animation so reopening replays
 * fresh, but leave the cards visible — they're carried back up
 * inside the drawer just like they came down. */
.desk-drawer-root:not(.is-open) .desk-card {
  animation: none;
  transform: rotate(var(--desk-card-rest, 0deg));
}

/* Hover + active states keep their existing transitions, but the
 * !important transform override has to cover the resting rotation
 * too (otherwise the animation's `rotate(var(...))` survives). */
.desk-card:hover {
  transform: translateY(-2px) rotate(0deg) scale(1) !important;
  background: rgba(255, 255, 255, 0.97);
  border-color: var(--desk-ink-55);
  box-shadow: 3px 4px 0 color-mix(in srgb, var(--ink, #1f2a25) 14%, transparent),
              0 1px 0 rgba(255,255,255,0.9) inset;
}
.desk-card.is-active {
  /* Lightest available cream so the active card pops against
   * whichever compartment tint sits behind it. */
  background: var(--surface, #FBF6E7);
  border-color: var(--desk-wood);
  box-shadow: 0 6px 14px -8px color-mix(in srgb, var(--desk-wood) 50%, transparent);
  transform: translateY(-1px) rotate(0deg) scale(1) !important;
}

.desk-card-glyph {
  width: 28px;
  height: 28px;
  /* Solid white background so the icon stroke reads clearly against
   * both the card and the compartment tint behind it. */
  background: rgba(255, 255, 255, 0.95);
  border: 1px solid color-mix(in srgb, var(--ink, #1f2a25) 28%, transparent);
  display: grid;
  place-items: center;
  border-radius: 0;
  /* Subtle inner-top highlight makes it look engraved/stamped */
  box-shadow: 0 1px 0 rgba(255,255,255,0.8) inset;
}
.desk-card-glyph svg {
  width: 15px;
  height: 15px;
  stroke-width: 1.4;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.desk-comp[data-group="main"]     .desk-card-glyph svg { stroke: var(--desk-butter); }
.desk-comp[data-group="study"]    .desk-card-glyph svg { stroke: var(--desk-sage);   }
.desk-comp[data-group="progress"] .desk-card-glyph svg { stroke: var(--desk-coral);  }
.desk-comp[data-group="account"]  .desk-card-glyph svg { stroke: var(--desk-you);    }

.desk-card-body { min-width: 0; }
.desk-card-name-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.desk-card-name {
  font-family: 'Fraunces', Georgia, serif;
  font-style: italic;
  font-size: 17px;
  line-height: 1;
  color: var(--desk-wood);
}
.desk-card-here {
  font-size: 9px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--desk-coral);
}
.desk-card-hint {
  font-size: 10px;
  letter-spacing: 0.04em;
  /* 65% ink reads clearly on the now-solid white card surface */
  color: color-mix(in srgb, var(--ink, #1f2a25) 65%, transparent);
  margin-top: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.desk-card-meta {
  margin-top: 5px;
  font-size: 9px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-family: 'DM Mono', monospace;
}
.desk-comp[data-group="main"]     .desk-card-meta { color: var(--desk-butter); }
.desk-comp[data-group="study"]    .desk-card-meta { color: var(--desk-sage);   }
.desk-comp[data-group="progress"] .desk-card-meta { color: var(--desk-coral);  }
.desk-comp[data-group="account"]  .desk-card-meta { color: var(--desk-you);    }

/* ── Wooden drawer pull at the bottom edge ── */
.desk-drawer-pull {
  height: 36px;
  background: repeating-linear-gradient(
    180deg,
    #D9C69A 0 2px,
    #C8B283 2px 4px,
    #D9C69A 4px 8px
  );
  border-top: 1px solid var(--desk-wood);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  cursor: pointer;
}
.desk-drawer-pull-knob {
  width: 72px;
  height: 14px;
  background: var(--desk-wood);
  border-radius: 7px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15);
  /* Settles with a tiny wobble after the drawer reaches the stop —
   * runs once on open, kicks in after the drawer slide finishes. */
  transform-origin: center top;
}
.desk-drawer-root.is-open .desk-drawer-pull-knob {
  animation: desk-knob-wobble 520ms cubic-bezier(0.32, 1.18, 0.55, 1) 460ms both;
}
@keyframes desk-knob-wobble {
  0%   { transform: translateY(-1.5px); }
  50%  { transform: translateY(0); }
  75%  { transform: translateY(-0.5px); }
  100% { transform: translateY(0); }
}
/* Hover on the entire pull bar: knob lengthens slightly toward
 * cursor, hinting it's grabbable. */
.desk-drawer-pull:hover .desk-drawer-pull-knob {
  width: 84px;
  transition: width 180ms cubic-bezier(0.2, 0.9, 0.3, 1);
}
.desk-drawer-pull-hint-left,
.desk-drawer-pull-hint-right {
  position: absolute;
  font-size: 9px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ink, #1f2a25) 65%, transparent);
}
.desk-drawer-pull-hint-left  { left: 24px; }
.desk-drawer-pull-hint-right { right: 24px; }

/* ── Concept badge (top-of-page reminder we're on the concept) ── */
body.desk-concept::before {
  content: 'CONCEPT · DESK DRAWER';
  position: fixed;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  font-family: 'DM Mono', ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 0.2em;
  background: var(--desk-wood);
  color: var(--desk-cream-2);
  padding: 4px 14px;
  border-bottom-left-radius: 6px;
  border-bottom-right-radius: 6px;
  pointer-events: none;
}

/* ── Page transition ──
 * When a new tab becomes active, slide it in from below with a fade.
 * Re-fires every time `.active` is added (different panels each get
 * their own first-mount animation), so it works for both
 * drawer-driven navigation and the original sidebar fallback. */
body.desk-concept .tab-panel.active {
  animation: desk-page-in 380ms cubic-bezier(0.22, 0.8, 0.3, 1) both;
  /* will-change kept off because tab-panels are huge — the animation
   * is short and runs once per nav; a layer-promotion of the full
   * panel costs more than it saves. opacity + transform are still
   * compositor-friendly without will-change for one-shot animations. */
}
@keyframes desk-page-in {
  0% {
    opacity: 0;
    transform: translateY(14px) scale(0.995);
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
/* The first tab visible on initial page load also gets the animation
 * — feels like the app "settles in" on load. If that's not wanted,
 * remove the .active rule above and instead key off a body class
 * the JS toggles only after first navigation. */

/* ── Respect reduced motion ── */
@media (prefers-reduced-motion: reduce) {
  .desk-drawer,
  .desk-drawer-scrim {
    transition: none;
  }
  .desk-card {
    transform: none !important;
    opacity: 1 !important;
    animation: none !important;
  }
  .desk-drawer-pull-knob { animation: none !important; }
  body.desk-concept .tab-panel.active { animation: none; }
}

/* ── Responsive: stack columns on small screens ── */
@media (max-width: 900px) {
  .desk-drawer-grid { grid-template-columns: repeat(2, 1fr); }
  .desk-comp { border-right: 1px solid var(--desk-ink-25); border-bottom: 1px solid var(--desk-ink-25); }
  .desk-drawer-head { padding: 12px 16px; gap: 12px; flex-wrap: wrap; }
  .desk-drawer-stats { gap: 10px; }
}
@media (max-width: 560px) {
  .desk-drawer-grid { grid-template-columns: 1fr; }
  .desk-comp { min-height: auto; }
}
