/*
 * Showcase-only styles (index.html): the hero, the component panels, the
 * attribute table, the preview stage and the outro. Shared page
 * chrome (tokens, the top bar, code blocks, placeholders) lives in
 * docs/site.css.
 */

/* The showcase panels render from docs/data.js; hold their space so the
   footer doesn't flash at the top and then leap away */
#panels:empty { min-height: 200vh; }

/* ======================= Scroll progress ======================= */
.scroll-progress {
  position:         fixed;
  inset-inline:     0;
  top:              0;
  height:           3px;
  z-index:          60;
  background:       var(--accent);
  transform:        scaleX(0);
  transform-origin: 0 0;
  pointer-events:   none;
}
[dir="rtl"] .scroll-progress { transform-origin: 100% 0; }

/* ============================ Hero ============================ */
/* A full-viewport azure opening with real depth: a diagonal tonal wash over
   the brand hue, a top-left highlight and bottom-right shade, slow-drifting
   light blobs and a film-grain overlay. Azure is the same value in light and
   dark, so the panel and its white text stay legible in both. overflow:
   hidden clips the wobble canvas / glow bleed (the hero is not a sticky
   ancestor, so sticky is unaffected). */
.hero {
  position:        relative;
  box-sizing:      border-box;
  min-height:      100vh;
  min-height:      100dvh;
  margin:          0;
  padding:         clamp(64px, 11vh, 132px) clamp(24px, 5vw, 80px);
  display:         flex;
  align-items:     center;
  overflow:        hidden;
  color:           #FFFFFF;
  background:
    radial-gradient(110% 85% at 10% -10%, color-mix(in srgb, #FFFFFF 22%, transparent), transparent 56%),
    radial-gradient(95% 90%  at 102% 114%, color-mix(in srgb, #001B33 46%, transparent), transparent 58%),
    linear-gradient(158deg,
      color-mix(in srgb, var(--jelly-color-background-azure, #0077CC) 84%, #66D1FF),
      var(--jelly-color-background-azure, #0077CC) 46%,
      color-mix(in srgb, var(--jelly-color-background-azure, #0077CC) 86%, #002B55)),
    var(--jelly-color-background-azure, #0077CC);
}

/* Decorative depth layers behind the content */
.hero-backdrop { position: absolute; inset: 0; pointer-events: none; }

.hero-backdrop .glow {
  position:      absolute;
  aspect-ratio:  1;
  border-radius: 50%;
  filter:        blur(64px);
  will-change:   transform;
}
.hero-backdrop .g1 {
  width: min(54vw, 780px);
  left:  -14%;
  top:   -22%;
  background: radial-gradient(circle, rgba(140, 214, 255, 0.5), transparent 66%);
  animation:  hero-drift 34s ease-in-out infinite alternate;
}
.hero-backdrop .g2 {
  width: min(44vw, 640px);
  right: -10%;
  top:   4%;
  background: radial-gradient(circle, rgba(64, 227, 199, 0.26), transparent 66%);
  animation:  hero-drift 46s ease-in-out infinite alternate-reverse;
}
.hero-backdrop .g3 {
  width:  min(40vw, 580px);
  left:   28%;
  bottom: -20%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.18), transparent 62%);
  animation:  hero-drift 52s ease-in-out infinite alternate;
  animation-delay: -18s;
}
@keyframes hero-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(5vw, 4vh, 0) scale(1.1); }
}

/* Fine monochrome grain kills the flat, poster-blue feel */
.hero-backdrop .grain {
  position:   absolute;
  inset:      0;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E") repeat;
  background-size: 180px 180px;
  opacity:         0.26;
  mix-blend-mode:  overlay;
}

.hero-grid {
  position:      relative;
  z-index:       1; /* keep the copy above the illustration where they meet */
  width:         min(1040px, 100%);
  margin-inline: auto;
}

/* Allow the copy to shrink below its content's natural width, or the headline
   would push the hero past a narrow viewport */
.hero-copy { min-width: 0; }

/* The Lottie illustration is a big decorative piece over on the right so it
   clears the left-aligned copy. It is positioned against the hero (not the
   centred copy column) and pushed down past the bottom edge, so the hero's
   overflow:hidden crops her lower half and she peeks up from the fold. The
   translate is a percentage of her own height, so the crop scales with the
   size at every viewport. */
.hero-anim {
  position:         absolute;
  inset-inline-end: clamp(-54px, calc(2vw - 30px), 26px);
  bottom:           0;
  width:            min(780px, 62vw);
  /* The artwork has ~13% empty canvas below the figure; translate past that so
     she seats on the bottom edge with no blue gap, cropping only her lower body */
  transform:        translateY(23%);
  pointer-events:   none;
}
.hero-lottie {
  width:        100%;
  aspect-ratio: 1;
  /* Nothing to see until the player + JSON arrive; fade in when ready so the
     illustration never pops in mid-frame */
  opacity:      0;
  transition:   opacity 0.6s ease;
}
.hero-lottie[data-ready="true"] { opacity: 1; }
.hero-lottie svg { display: block; width: 100%; height: 100%; }

@media (prefers-reduced-motion: reduce) {
  :root:not([data-jelly-motion="no-preference"]) .hero-lottie { transition: none; }
}

:root[data-jelly-motion="reduce"] .hero-lottie { transition: none; }

.hero h1 {
  margin: 0;
  color:  color-mix(in srgb, #FFFFFF 88%, transparent);
  font:   700 clamp(34px, 5.6vw, 84px)/0.98 var(--display);
  letter-spacing: -0.03em;
}

.hero .lede {
  max-width: 52ch;
  margin:    22px 0 0;
  color:     color-mix(in srgb, #FFFFFF 84%, transparent);
  font-size: clamp(16px, 1.7vw, 18.5px);
}

/* Proof chips: the marketing numbers, scannable in one glance - real
   jelly-badges (the docs dogfood the components they document) */
.hero-stats {
  display:   flex;
  flex-wrap: wrap;
  gap:       9px;
  margin:    24px 0 0;
}

/* The hero card is a fixed blue surface, not theme-driven, so its outline
   pills keep white labels and rims regardless of the page's light / dark mode
   (the outline badge otherwise draws its label in the theme text token). */
.hero-stats jelly-badge {
  --jelly-color-foreground-default:  #FFFFFF;
  --jelly-color-background-white: #FFFFFF;
}

.hero-links {
  display:     flex;
  flex-wrap:   wrap;
  align-items: center;
  gap:         14px;
  margin-top:  30px;
  /* The button's soft body is inset ~4px inside its host box, more than the
     stat badges above and the code panel below; pull the row back so the
     first button's left edge lines up with them */
  margin-inline-start: -5px;
}

/* The quickstart sits on the blue, so it becomes a dark glass panel with light
   code text for legibility - dressed as a tiny editor window. It is nearly
   opaque so the illustration reads as peeking out from behind it rather than
   bleeding through the glass. */
.quickstart {
  position:      relative;
  z-index:       1;
  margin-top:    30px;
  max-width:     620px;
  border:        1px solid color-mix(in srgb, #FFFFFF 26%, transparent);
  border-radius: 14px;
  background:    color-mix(in srgb, #001B33 92%, transparent);
  backdrop-filter: blur(6px);
}
.quickstart-head {
  display:       flex;
  align-items:   center;
  gap:           6px;
  padding:       10px 14px;
  border-bottom: 1px solid color-mix(in srgb, #FFFFFF 14%, transparent);
}
.quickstart-head i {
  width:         9px;
  height:        9px;
  border-radius: 50%;
  background:    color-mix(in srgb, #FFFFFF 30%, transparent);
}
.quickstart-head code {
  margin-inline-start: 8px;
  font:                600 11px/1 var(--mono);
  letter-spacing:      0.04em;
  color:               color-mix(in srgb, #FFFFFF 58%, transparent);
}
.quickstart pre {
  margin:      0;
  padding:     14px 18px 16px;
  overflow-x:  auto;
  font-size:   13px;
  line-height: 1.6;
  color:       color-mix(in srgb, #FFFFFF 92%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  :root:not([data-jelly-motion="no-preference"]) .hero-backdrop .glow { animation: none; }
}

:root[data-jelly-motion="reduce"] .hero-backdrop .glow { animation: none; }

/* The illustration is intentionally large, so it needs a wide viewport to sit
   beside the copy without crowding the code block. Below that it is hidden -
  and because it is display:none it never loads its payload. */
@media (max-width: 1300px) {
  .hero-anim { display: none; }
}

/* ============================ Panels ============================ */
/* Each panel is at least one viewport-height section (minus the sticky top
   bar). The table and preview are fully interactive: click an option
   badge or type into a text field and the preview + snippet update. */
.panel {
  position:      relative;
  display:       flex;
  min-height:    calc(100vh - var(--header-h));
  min-height:    calc(100dvh - var(--header-h));
  border-bottom: 1px solid var(--line);
}

.scene {
  display:     flex;
  align-items: center;
  width:       100%;
  /* Clip the components' decorative canvas bleed horizontally so it can't
     widen the page; vertical stays visible so tall tables flow naturally. */
  overflow-x:  clip;
}

.panel-grid {
  display:               grid;
  grid-template-columns:  minmax(0, 5fr) minmax(0, 6fr);
  gap:                   clamp(24px, 4vw, 64px);
  align-items:           center;
  box-sizing:            border-box;
  width:                 min(1360px, 100%);
  margin-inline:         auto;
  padding:               clamp(16px, 3vh, 40px) clamp(20px, 4vw, 56px);
}

/* Docs column */
.doc { min-width: 0; min-height: 0; max-height: 100%; }

.doc .kicker {
  margin:         0 0 8px;
  font:           660 11px/1 var(--mono);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color:          var(--accent);
}

.doc h2 {
  margin: 0;
  font:   650 clamp(26px, 3vw, 38px)/1.1 var(--display);
  letter-spacing: -0.02em;
}

.doc .summary {
  margin:    10px 0 0;
  max-width: 55ch;
  color:     var(--muted);
}

/* Attribute table: each row shows an attribute and ALL of its options using
   the library's own components - clickable jelly-badges for enums / booleans
   / numbers, an editable jelly-input for text. Whatever you pick or type
   lands on the live preview and the snippet. */
.attrs {
  margin-top: 26px;
}

.attr {
  display:               grid;
  grid-template-columns: minmax(0, 150px) minmax(0, 1fr);
  align-items:           center; /* centre the name against its (wrapping) option row */
  gap:                   6px 24px;
  padding:               14px 12px;
  border-top:            1px solid var(--line);
}
.attr:first-child { border-top: 0; }

.attr-name code {
  font:       640 13px/1.7 var(--mono);
  color:      var(--text);
  word-break: break-word;
}

/* Every option shows at once as a real jelly-chip (dogfooding): the current
   one selected (accent), the rest at rest (platinum). They wrap onto their own
   lines as needed and each is clickable - it sets that option directly. */
.attr-options {
  display:     flex;
  flex-wrap:   wrap;
  align-items: center;
  gap:         8px;
}
.attr-chip { vertical-align: middle; }
.attr-field { display: inline-block; width: 100%; max-width: 260px; }

.note {
  margin:    16px 12px 0;
  color:     var(--muted);
  font-size: 13px;
}

/* The live-updating HTML snippet (block styles shared in site.css) */
.doc .code     { margin-top: 24px; }
.doc .code pre { max-height: 150px; }

.api-link {
  display:         inline-block;
  margin-top:      20px;
  font:            600 14px var(--body);
  color:           var(--accent);
  text-decoration: none;
}
.api-link:hover { text-decoration: underline; }

/* The preview stage. The whole .scene pins, so the frame itself just fills
   its column and rides along inside the pinned scene. The backdrop is a
   Photoshop-style transparency checkerboard: a neutral canvas that every
   fill reads against - white components interrupt the checks, so they stay
   clearly visible where a flat background would swallow them. */
.stage { min-width: 0; min-height: 0; max-height: 100%; }

.stage-frame {
  position:   relative;
  width:      100%;
  height:     min(62vh, 520px);
  max-height: 100%;

  display:         flex;
  align-items:     center;
  justify-content: center;

  border:        1px solid var(--line);
  border-radius: 22px;
  background:
    repeating-conic-gradient(color-mix(in srgb, var(--line) 38%, var(--surface)) 0% 25%, transparent 0% 50%) 0 0 / 26px 26px,
    var(--surface);
  overflow: hidden;
}

/* Fill the frame exactly so it centers the demo without adding its own
   scrollbars; the frame already clips any rare oversized preview. */
.stage-inner {
  display:         flex;
  flex-direction:  column;
  flex-wrap:       wrap;
  align-items:     center;
  justify-content: center;
  align-content:   center;
  gap:             16px;
  width:           100%;
  height:          100%;
  padding:         clamp(18px, 3vw, 40px);
  overflow:        hidden;
}

/* Ease the preview's size changes so small ↔ medium ↔ large glides rather
   than snapping (the canvas body follows via its ResizeObserver). Scoped to
   the size-scaling controls - chip / divider / resizable keep their own
   transitions. */
.stage-inner :is(jelly-button, jelly-icon-button, jelly-input, jelly-textarea,
  jelly-checkbox, jelly-radio, jelly-switch, jelly-slider, jelly-badge,
  jelly-kbd, jelly-spinner, jelly-select, jelly-segmented, jelly-otp,
  jelly-progress, jelly-alert, jelly-card, jelly-label, jelly-tooltip) {
  transition: width 0.42s cubic-bezier(0.4, 0, 0.2, 1),
              height 0.42s cubic-bezier(0.4, 0, 0.2, 1);
}

@media (prefers-reduced-motion: reduce) {
  :root:not([data-jelly-motion="no-preference"]) .stage-inner
    :is(jelly-button, jelly-icon-button, jelly-input, jelly-textarea,
      jelly-checkbox, jelly-radio, jelly-switch, jelly-slider, jelly-badge,
      jelly-kbd, jelly-spinner, jelly-select, jelly-segmented, jelly-otp,
      jelly-progress, jelly-alert, jelly-card, jelly-label, jelly-tooltip) { transition: none; }
}

:root[data-jelly-motion="reduce"] .stage-inner :is(jelly-button,
  jelly-icon-button, jelly-input, jelly-textarea, jelly-checkbox, jelly-radio,
  jelly-switch, jelly-slider, jelly-badge, jelly-kbd, jelly-spinner,
  jelly-select, jelly-segmented, jelly-otp, jelly-progress, jelly-alert,
  jelly-card, jelly-label, jelly-tooltip) { transition: none; }

/* A tidy panel for the jelly-tabs preview: a heading + line of copy on a soft
   surface, so switching tabs shows something more finished than bare text */
.stage-inner .pg-tab {
  padding:       clamp(14px, 2.4vw, 22px);
  border-radius: 14px;
  background:    color-mix(in srgb, var(--accent) 6%, var(--surface));
  border:        1px solid var(--line);
  max-width:     34ch;
  text-align:    start;
}
.stage-inner .pg-tab h3 {
  margin: 0 0 6px;
  font:   660 16px/1.2 var(--display);
  color:  var(--text);
}
.stage-inner .pg-tab p { margin: 0; color: var(--muted); font-size: 14px; }

/* jelly-resizable panes: gray tiles, inset 4px and rounded, so each split
   section reads as its own filled card against the preview's white ground.
   The colors are literal (not theme tokens) so the tiles stay legible in
   both light and dark - the preview backdrop is always white here. */
.stage-inner .pg-pane {
  display:         grid;
  place-items:     center;
  /* No explicit height: the pane is a flex item (the component sets
     flex: 1 1 0), so flex-grow and cross-axis stretch fill the cell while
     accounting for the margin - an explicit height: 100% would ignore the
     margin, overflow by 8px and clip unevenly at the bottom. */
  margin:          4px;
  border-radius:   10px;
  background:      #E8E9ED;
  color:           #1F2430;
  font:            600 15px/1 var(--display);
}

.stage-events {
  position:           absolute;
  inset-inline-end:   14px;
  bottom:             12px;
  display:            flex;
  flex-direction:     column-reverse;
  align-items:        flex-end;
  gap:                6px;
  pointer-events:     none;
}

/* The fired-event ticker: real jelly-badges dropped in by the showcase, so
   only the fade-out is styled here */
.event-chip {
  opacity:    0.95;
  transition: opacity .6s ease, transform .6s ease;
}
.event-chip.fading {
  opacity:   0;
  transform: translateY(-6px);
}

@media (prefers-reduced-motion: reduce) {
  :root:not([data-jelly-motion="no-preference"]) .event-chip { transition: none; }
  :root:not([data-jelly-motion="no-preference"]) .event-chip.fading { transform: none; }
}

:root[data-jelly-motion="reduce"] .event-chip { transition: none; }
:root[data-jelly-motion="reduce"] .event-chip.fading { transform: none; }

/* ============================ Outro ============================ */
/* The send-off at the very bottom: a celebratory Lottie (lazy-loaded like the
   hero's) over the footer text, aligned as the final snap stop. */
.outro {
  display:         flex;
  flex-direction:  column;
  align-items:     center;
  justify-content: center;
  gap:             8px;
  min-height:      calc(100vh - var(--header-h));
  min-height:      calc(100dvh - var(--header-h));
  padding:         48px clamp(20px, 4vw, 56px) 64px;
  text-align:      center;
}

.outro-anim {
  width:          min(380px, 68vw);
  pointer-events: none;
}

.footer-lottie {
  width:        100%;
  aspect-ratio: 1;
  /* Nothing to see until the player + JSON arrive; fade in when ready */
  opacity:      0;
  transition:   opacity 0.6s ease;
}
.footer-lottie[data-ready="true"] { opacity: 1; }
.footer-lottie svg { display: block; width: 100%; height: 100%; }

.outro h2 {
  margin: 0;
  font:   680 clamp(24px, 3vw, 36px)/1.15 var(--display);
  letter-spacing: -0.02em;
  color:  var(--text);
}

.outro p {
  margin:    6px 0 0;
  max-width: 52ch;
}

@media (prefers-reduced-motion: reduce) {
  :root:not([data-jelly-motion="no-preference"]) .footer-lottie { transition: none; }
}

:root[data-jelly-motion="reduce"] .footer-lottie { transition: none; }

/* ============================ Mobile ============================ */
/* Narrow screens stack each panel naturally: sections grow to their content
   and the preview leads the docs. */
@media (max-width: 900px) {
  .panel { min-height: 0; }

  .scene { display: block; }

  .panel-grid {
    grid-template-columns: 1fr;
    gap:                   20px;
    align-items:           start;
    padding:               clamp(28px, 6vw, 48px) clamp(18px, 5vw, 32px);
  }

  /* The preview leads, the docs follow beneath it */
  .stage       { order: -1; max-height: none; }
  .stage-frame { height: min(46vh, 360px); }

  .doc { max-height: none; }

  /* Stack each row so the value component gets the full column width */
  .attr {
    grid-template-columns: 1fr;
    gap:                   4px;
  }

  .attr-field { max-width: none; }

  /* Wrap long code snippets instead of scrolling them sideways */
  .code pre { white-space: pre-wrap; word-break: break-word; }

  .outro { min-height: 0; }
}
