@import url("https://fonts.googleapis.com/css2?family=Fredoka:wght@500;600&family=Nunito:wght@400;700;800&display=swap");

/* Scratch block-kit — static, pixel-accurate recreations of real Scratch
   blocks, sourced from the official Scratch Blocks Figma community file.
   These are REFERENCE images, not interactive: a child looks at a page
   built from this kit and reproduces the same block stack in the real
   Scratch editor. So fidelity to real Scratch (shape, color, spacing)
   matters more than interactivity here.

   Shape technique: every block has a fixed-size "cap" (an SVG containing
   the puzzle-piece notch/bump curves) plus a "body" that stretches to fit
   its label/input content via normal flex layout. The cap is taller than
   the block's nominal height because the bottom "bump" deliberately
   overflows past the body — that overflow is what visually nests into the
   next block's top notch when stacked with no gap. See each block-family
   comment below for its exact numbers (all taken directly from the Figma
   file, not guessed). */

.sscript {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Pulls each following block up so its top notch nests under the
   previous block's overflowing bottom bump (~12px, matching the cap
   shape's own overflow amount below). Skip on the very first block. */
.sscript > .sblock:not(:first-child) {
  margin-top: -12px;
}

.sblock {
  position: relative;
  display: inline-flex;
  align-items: flex-start;
  font-family: "Roboto", "Segoe UI", sans-serif;
}

.sblock__cap {
  display: block;
  flex: 0 0 auto;
}

.sblock__cap .sfill {
  fill: var(--fill);
}

.sblock__cap .sstroke {
  fill: none;
  stroke: var(--border);
  stroke-width: 2;
}

.sblock__body {
  flex: 0 0 auto;
  margin-left: -2px; /* tucks 2px under the cap to hide the seam */
  height: 68px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 8px 0 16px;
  background: var(--fill);
  border: 2px solid var(--border);
  border-left: none;
  border-radius: 0 9px 9px 0;
  color: #fff;
  font-size: 24px;
  white-space: nowrap;
}

/* Hat blocks (events) have no top notch — a rounded dome instead — so
   their body sits 24px down from the cap's top, per the Figma spec. */
.sblock--hat .sblock__body {
  margin-top: 24px;
}

/* Hides the hairline seam where the cap's own right-edge stroke meets
   the body's border — the real Scratch renderer does the same thing
   (a thin fill-colored strip laid right over the seam). */
.sblock__seam {
  position: absolute;
  top: 2px;
  width: 4px;
  height: 64px;
  background: var(--fill);
}

.sblock--stack .sblock__seam {
  left: 86px;
}

.sblock--hat .sblock__seam {
  top: 26px;
  left: 147px;
}

.sblock__input {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  padding: 8px 12px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 20px;
  color: #575e75;
  font-size: 24px;
  line-height: 1;
}

/* Dropdown selector inside a block (sound/sprite/backdrop names, or a
   fixed option list like graphic-effect names). Two shapes seen in the
   real blocks: --pill (rounded-full, used for referencing external
   things like a sound name) and --value (barely-rounded rect, used for
   fixed internal option lists like "color"/"fisheye"/etc). Defaults to
   the block's own category color; a couple of real blocks (e.g. "play
   sound") use a slightly darker shade of that color instead — override
   with an inline style on that instance rather than adding a new
   variable for a single case. */
.sblock__dropdown {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--fill);
  border: 1px solid var(--border);
  color: #fff;
  font-size: 24px;
  line-height: 1;
  white-space: nowrap;
}

.sblock__dropdown--pill {
  border-radius: 20px;
}

.sblock__dropdown--value {
  border-radius: 4px;
}

.sblock__dropdown-arrow {
  width: 12.71px;
  height: 8.79px;
  flex: 0 0 auto;
}

/* C-blocks (control_repeat, control_forever, control_if_then, ...) —
   a genuinely different, more complex shape family than stack/hat: three
   pieces stacked vertically (top bar, an indented "mouth" for nested
   blocks, bottom bar), plus a small connector cover between top and
   bottom. Same architecture as stack/hat (SVG cap + CSS rounded-rect
   body) applied to each of the top and bottom bars separately.

   Path data source: rather than re-deriving this from Figma (hit the
   Figma MCP rate limit while building this), these paths are cropped
   directly out of the pre-made assets/scratch-blocks-svg/control/
   control_repeat.svg via each <svg>'s viewBox — that file's own
   coordinate space is reused as-is (e.g. viewBox="0 100 125 85" for the
   top cap), not renormalized, so no path numbers were hand-edited. See
   CLAUDE.md's "Adding a new project" checklist: check the pre-made
   library before hand-deriving a new shape from Figma. */
.sblock--loop {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.sblock--loop .sblock__cap {
  display: block;
  flex: 0 0 auto;
}

.sblock__loop-row {
  position: relative;
  display: inline-flex;
  align-items: flex-start;
}

.sblock__loop-mouth {
  position: relative;
  margin-left: 37px; /* matches the C-block's own wall thickness — this is
                         the indent nested blocks sit at */
  margin-top: -12px; /* same connector overlap convention as .sscript */
  margin-bottom: -12px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.sblock__loop-mouth::before {
  /* The C-block's left wall, drawn in CSS so it always spans the mouth's
     actual rendered height — NOT a fixed-size SVG patch. An earlier
     version used a hand-sized connector SVG tuned for exactly 2 nested
     blocks; it visibly broke (gap in the wall) the moment a project
     nested a 3rd block, since the patch's height didn't grow with the
     content. This rule fixes that structurally: any number of nested
     blocks works with zero per-project tuning. See CLAUDE.md bug #6. */
  content: "";
  position: absolute;
  top: 0;
  left: -37px;
  width: 37px;
  height: 100%;
  background: var(--fill);
  border-left: 2px solid var(--border);
  box-sizing: border-box;
}

.sblock__loop-mouth > .sblock:not(:first-child) {
  margin-top: -12px;
}

.sblock__body--short {
  height: 52px;
}

.sblock__icon {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
}

/* Small numbered badge pinned to the top-left corner of a block,
   matching the same number on that block's category chip in the legend
   above — so a child can look at any block in the stack and immediately
   find which sidebar tab it came from, without reading. */
.sblock__tag {
  position: absolute;
  top: -14px;
  left: -14px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--fill);
  border: 3px solid #fff;
  box-shadow: 0 0 0 2px var(--border);
  color: #fff;
  font-family: "Fredoka", "Roboto", sans-serif;
  font-weight: 600;
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}

/* Category colors, taken directly from the Figma file's own fill/border
   values for each block family (not approximated). */
.cat-motion   { --fill: #4c97ff; --border: #3373cc; }
.cat-looks    { --fill: #9966ff; --border: #774dcb; }
.cat-sound    { --fill: #cf63cf; --border: #bd42bd; }
.cat-events   { --fill: #ffbf00; --border: #cc9900; }
.cat-control  { --fill: #ffab19; --border: #cf8b17; }
.cat-sensing  { --fill: #5cb1d6; --border: #2e8eb8; }
.cat-operators{ --fill: #59c059; --border: #389438; }
.cat-variables{ --fill: #ff8c1a; --border: #db6e00; }
.cat-lists    { --fill: #ff661a; --border: #e64d00; } /* confirmed 2026-09-23 from
                  assets/scratch-blocks-svg/categories/category_lists_strip.svg's
                  own fill values, not Figma (Figma was rate-limited) — a real
                  asset from the same source library counts as verified, a guess
                  from memory of Scratch's public palette would not have. */
/* .cat-myblocks and .cat-pen are NOT yet defined — no pre-made SVG for either
   category exists in assets/scratch-blocks-svg/, and Figma is rate-limited
   (Starter plan). Verify via Figma before the first project that needs either
   category; don't add a color here from memory before then. See
   data/blocks-catalog.json's "verified": false flag on both. */

/* The notebook paper is now the WHOLE page (full viewport width/height),
   not a small card floating in a separate background — a card left large
   blank margins on anything wider than ~680px. Ruled lines and the
   spiral-binding strip both run edge-to-edge here; .sbook below is just a
   comfortable-reading-width content column sitting on top of this paper,
   with no card styling of its own (no border/shadow/background) so the
   paper shows through uniformly everywhere, including beside the content
   on wide screens. */
.spage {
  position: relative;
  min-height: 100vh;
  margin: 0;
  background-color: #fffdf7;
  background-image: repeating-linear-gradient(
    to bottom,
    transparent,
    transparent 31px,
    #d7e6f2 31px,
    #d7e6f2 32px
  );
  font-family: "Nunito", "Segoe UI", sans-serif;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 40px 32px 64px 100px;
  box-sizing: border-box;
}

.spage::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 64px;
  background-color: #f3efe2;
  background-image: radial-gradient(circle, #e7e2d6 8px, transparent 8.5px);
  background-size: 64px 48px;
  background-position: 0 24px;
  border-right: 2px dashed #d8cfb4;
}

.sbook {
  width: 100%;
  max-width: 640px;
  box-sizing: border-box;
}

.sbook__home {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #ffffff;
  color: #2b3452;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  padding: 6px 16px;
  border-radius: 999px;
  border: 2px solid #c7d2e0;
  margin-bottom: 14px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
  transition: transform 0.1s ease, box-shadow 0.1s ease;
}

.sbook__home:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
}

.sbook__badge {
  display: inline-block;
  background: #ffbf00;
  color: #2b3452;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 6px 18px;
  border-radius: 999px;
  border: 2px solid #cc9900;
  margin-bottom: 16px;
  transform: rotate(-4deg);
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.18);
}

.sbook__title {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: #2b3452;
  font-size: 36px;
  font-weight: 600;
  margin: 0 0 16px;
  line-height: 1.15;
}

.sbook__intro {
  color: #4b5266;
  font-size: 18px;
  line-height: 1.55;
  margin: 0 0 28px;
}

.sbook__section-title {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: #2b3452;
  font-size: 20px;
  font-weight: 600;
  margin: 0 0 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* "Grab these blocks" legend — mirrors the real Scratch sidebar's colored
   category tabs, numbered to match the tags pinned on each block below,
   so a child can match a block's badge number to a tab here. */
.slegend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 32px;
}

.slegend__item {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #f7f4ea;
  border: 2px solid #ece6d4;
  border-radius: 14px;
  padding: 8px 16px 8px 10px;
}

.slegend__num {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--fill);
  border: 2px solid var(--border);
  color: #fff;
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.slegend__label {
  color: #2b3452;
  font-weight: 700;
  font-size: 16px;
}

.sstage {
  background: #fff;
  border: 2px solid #e2e5ea;
  border-radius: 16px;
  padding: 44px 40px 32px;
  max-width: 100%;
  box-sizing: border-box;
  /* Blocks have fixed, non-responsive widths (real Scratch block
     proportions, pulled from Figma) and a wide multi-input block can
     exceed a phone's viewport width. Scroll horizontally INSIDE this box
     rather than letting it push the whole page wider — the 44px top
     padding already clears the -14px numbered-tag overhang, so nothing
     gets clipped by switching off "visible". */
  overflow-x: auto;
}

.sbook__footer {
  margin-top: 28px;
  padding-top: 20px;
  border-top: 2px dashed #e8dfc8;
  color: #6b7280;
  font-size: 16px;
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Outcome preview — a small mockup of the Scratch stage showing roughly
   what the finished project looks/feels like when run, so a child knows
   what they're aiming for before (or after) building it. Not pixel-exact
   to Scratch's own sprite art — illustrative, not literal. */
.spreview {
  position: relative;
  width: 100%;
  max-width: 420px;
  aspect-ratio: 4 / 3;
  margin: 0 0 32px;
  border-radius: 12px;
  border: 4px solid #2b3452;
  overflow: hidden;
  /* Real Scratch's default stage is plain white — this is the correct
     look for any project that DOESN'T ship a custom backdrop (most of
     them). Only set an inline background-image when the project actually
     has a downloadable backdrop asset; otherwise leave this default, or
     the preview would show as transparent (revealing the notebook lines
     through it) which doesn't match what the child will actually see. */
  background-color: #ffffff;
  background-size: cover;
  background-position: center;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}

/* Wraps a sprite (and optionally a speech bubble) as ONE positioned unit —
   set left/bottom/top on THIS element only. The bubble then anchors itself
   to the sprite automatically (always directly above it, tail pointing
   down into it), so the two can never drift apart the way two
   independently-hardcoded absolute positions did before. */
.spreview__actor {
  position: absolute;
}

.spreview__sprite {
  display: block;
  width: 17%; /* percentage, not a fixed px, so it scales with .spreview's
                 actual rendered width instead of assuming its max-width */
  min-width: 48px;
  max-width: 90px;
  height: auto;
  filter: drop-shadow(0 4px 4px rgba(0, 0, 0, 0.25));
}

.spreview__bubble {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-32%);
  margin-bottom: 10px;
  background: #fff;
  border: 3px solid #2b3452;
  border-radius: 16px;
  padding: 8px 16px;
  font-family: "Nunito", sans-serif;
  font-weight: 800;
  font-size: 20px;
  color: #2b3452;
  white-space: nowrap;
}

.spreview__bubble::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 32%;
  border: 10px solid transparent;
  border-top-color: #2b3452;
  border-bottom: 0;
}

.spreview__bubble::before {
  content: "";
  position: absolute;
  top: calc(100% - 4px);
  left: calc(32% + 3px);
  border: 8px solid transparent;
  border-top-color: #fff;
  border-bottom: 0;
  z-index: 1;
}

/* "Think" bubble variant — real Scratch draws a thought-cloud (rounder,
   trailing circles) instead of a speech bubble (pointed triangle tail),
   and the two read as visually distinct even to a non-reading child. Use
   .spreview__bubble--think in place of the default triangle tail, and
   add two .spreview__thought-dot elements between the bubble and the
   sprite (see the Thinking Cat project for the exact markup). */
.spreview__bubble--think {
  border-radius: 20px;
}

.spreview__bubble--think::after,
.spreview__bubble--think::before {
  display: none;
}

.spreview__thought-dot {
  position: absolute;
  background: #fff;
  border: 3px solid #2b3452;
  border-radius: 50%;
}

/* Downloadable project extras (backdrops/sprites) the child imports into
   Scratch before or while building. */
.sassets {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin: 0 0 32px;
}

.sasset-card {
  display: flex;
  flex-direction: column;
  width: 160px;
  background: #f7f4ea;
  border: 2px solid #ece6d4;
  border-radius: 14px;
  overflow: hidden;
  text-decoration: none;
}

.sasset-card__thumb {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
  border-bottom: 2px solid #ece6d4;
}

.sasset-card__body {
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.sasset-card__name {
  font-weight: 800;
  color: #2b3452;
  font-size: 14px;
}

.sasset-card__hint {
  color: #8b8577;
  font-size: 12px;
  line-height: 1.35;
}

.sasset-card__btn {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: #2b3452;
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  border-radius: 999px;
  padding: 7px 0;
}

/* Landing page (root index.html) — a table of contents styled as the
   book's cover + chapter list, sitting on the same full-bleed notebook
   paper as every project page. Regenerated from data/projects.json, not
   hand-edited — see ROADMAP.md's "Landing page" section. */
.sindex {
  width: 100%;
  max-width: 760px;
}

.sindex__hero {
  text-align: center;
  margin: 0 0 40px;
}

.sindex__hero-title {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: #2b3452;
  font-size: 44px;
  font-weight: 600;
  margin: 0 0 8px;
}

.sindex__hero-subtitle {
  color: #6b7280;
  font-size: 18px;
  margin: 0;
}

.sindex__chapter {
  margin-bottom: 40px;
}

.sindex__chapter-title {
  font-family: "Fredoka", "Nunito", sans-serif;
  color: #2b3452;
  font-size: 24px;
  font-weight: 600;
  margin: 0 0 4px;
}

.sindex__chapter-desc {
  color: #6b7280;
  font-size: 15px;
  margin: 0 0 18px;
}

.sindex__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 14px;
}

.sindex__tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  background: #f7f4ea;
  border: 2px solid #ece6d4;
  border-radius: 14px;
  padding: 18px 10px;
  text-decoration: none;
  transition: transform 0.12s, box-shadow 0.12s;
}

.sindex__tile:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.1);
}

.sindex__tile-emoji {
  font-size: 34px;
  line-height: 1;
}

.sindex__tile-num {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 12px;
  color: #a89f8a;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.sindex__tile-title {
  font-weight: 800;
  color: #2b3452;
  font-size: 14px;
  text-align: center;
  line-height: 1.25;
}

/* ===== Blocks reference page (glossary) =====
   Lightweight "chip" rendering, not the full pixel-perfect cap/body SVG
   system used in project diagrams — this page's job is informational
   (124 entries), not a build-along diagram, so a colored pill with the
   label text is enough. Generated by data/build-blocks-coverage.py from
   data/blocks-catalog.json + data/projects.json — don't hand-edit
   blocks-reference.html. */

.sref__category {
  margin-bottom: 36px;
}

.sref__category-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 4px;
}

.sref__category-dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  flex: 0 0 auto;
}

.sref__category-title {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 20px;
  color: #2b3452;
}

.sref__category-count {
  font-family: "Nunito", sans-serif;
  font-size: 13px;
  color: #7a8296;
}

.sref__unverified {
  font-family: "Nunito", sans-serif;
  font-size: 12px;
  color: #b8860b;
  background: #fff6dd;
  border: 1px solid #f0dca0;
  border-radius: 6px;
  padding: 2px 8px;
  margin-left: 4px;
}

.sref__grid {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 12px;
}

.sref__chip {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 14px;
  background: var(--fill);
  color: #ffffff;
  border: 2px solid var(--border);
  font-family: "Roboto", "Segoe UI", sans-serif;
  font-size: 13px;
  line-height: 1.3;
}

.sref__chip--stack,
.sref__chip--hat,
.sref__chip--c-block,
.sref__chip--cap {
  border-radius: 8px;
}

.sref__chip--reporter {
  border-radius: 999px;
}

.sref__chip--boolean {
  border-radius: 4px;
  clip-path: polygon(8px 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 8px 100%, 0 50%);
  padding-left: 18px;
  padding-right: 18px;
}

.sref__chip--taught {
  opacity: 1;
}

.sref__chip--untaught {
  opacity: 0.45;
  filter: grayscale(35%);
}

.sref__chip-taught-by {
  font-family: "Nunito", sans-serif;
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  opacity: 0.9;
}

.sref__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin: 16px 0 28px;
  font-family: "Nunito", sans-serif;
  font-size: 13px;
  color: #4a5168;
}

.sref__legend-item {
  display: flex;
  align-items: center;
  gap: 6px;
}

.sref__legend-swatch {
  width: 14px;
  height: 14px;
  border-radius: 4px;
  border: 2px solid #cf8b17;
  background: #ffab19;
}

.sref__legend-swatch--untaught {
  opacity: 0.45;
  filter: grayscale(35%);
}

.sref__progress {
  font-family: "Fredoka", "Nunito", sans-serif;
  font-weight: 600;
  font-size: 16px;
  color: #2b3452;
  background: #ffffff;
  border: 2px solid #c7d2e0;
  border-radius: 12px;
  padding: 12px 18px;
  margin-bottom: 24px;
  display: inline-block;
}
