/* ============================================================
   slides.css — slide layout system for technical presentations.
   Applies the デジタル庁 guidebook's discipline (clear hierarchy,
   one accent color, minimal data-ink, generous whitespace) to
   general slides. Templates link BOTH styles.css and this file.

   Canvas: 1920×1080. Every slide is .slide; scale it to fit with a
   wrapper (the deck-stage shell does this — see slides/deck-stage.js) — never zoom the browser.
   ============================================================ */

.slide {
  position: relative;
  width: 1920px;
  height: 1080px;
  background: var(--surface-card);
  color: var(--text-body);
  font-family: var(--font-sans);
  box-sizing: border-box;
  padding: var(--slide-margin-y) var(--slide-margin-x);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Top keyline — the guidebook's quiet brand signal */
.slide--keyline::before {
  content: "";
  position: absolute; left: 0; top: 0;
  width: 100%; height: 10px; background: var(--brand);
}

/* ---- Slide header: kicker + title + accent rule ---- */
.slide-kicker {
  font: var(--fw-bold) var(--fs-slide-kicker)/1.2 var(--font-sans);
  color: var(--blue-900);
  letter-spacing: var(--ls-wide);
  flex-shrink: 0;
}
.slide-title {
  margin: 12px 0 0;
  font: var(--fw-bold) var(--slide-title-size)/1.2 var(--font-sans);
  color: var(--text-strong);
  letter-spacing: var(--ls-tight);
  flex-shrink: 0;
}
/* Jump rate: --sm is the workhorse content-slide title; --lg is for
   covers / hero moments. Body copy sits far below both (see .points,
   .slide-lead etc.) so title vs. body contrast stays wide and slides
   never read as one flat size. */
.slide-title--sm { font-size: var(--fs-slide-title); }
.slide-title--lg { font-size: var(--fs-slide-title-lg); }
.slide-lead {
  margin: 24px 0 0;
  font: var(--fw-regular) var(--fs-slide-lead)/1.75 var(--font-sans);
  color: var(--text-body);
  max-width: 1200px;
}
.slide-rule {
  width: 72px; height: 6px; border-radius: 3px;
  background: var(--brand); margin: 24px 0 0;
  flex-shrink: 0;
}

/* ---- Footer: deck title (left) / page number (right) ---- */
.slide-foot {
  position: absolute; left: var(--slide-margin-x); right: var(--slide-margin-x);
  bottom: 48px;
  display: flex; align-items: center; justify-content: space-between;
  border-top: 1px solid var(--border-subtle); padding-top: 18px;
}
.slide-foot .src { font: var(--fw-regular) var(--fs-slide-foot) var(--font-sans); color: var(--text-subtle); }
.slide-foot .pg  { font: var(--fw-medium) var(--fs-slide-foot) var(--font-mono); color: var(--text-muted); font-variant-numeric: tabular-nums; }
/* Source / as-of note placed near a figure, table, stat or code block.
   The footer no longer carries the source — it now shows the deck title +
   page number — so any citation lives next to the content it qualifies. */
.slide-asof { margin-top: 10px; font: var(--fw-regular) 20px var(--font-sans); color: var(--text-subtle); }

/* Brand lockup (placeholder square mark + wordmark) */
.brand-lockup { display: inline-flex; align-items: center; gap: 12px; }
.brand-lockup .mark { width: 32px; height: 32px; border-radius: 6px; background: var(--brand); flex-shrink: 0; }
.brand-lockup .name { font: var(--fw-bold) 20px var(--font-sans); color: var(--text-strong); }

/* ---- Body layouts ----
   .slide-body is the ONE content block between the header and the
   footer. The slide is a flex column, so giving it auto top/bottom
   margins centers it in whatever room is left — short content sits
   in the middle of the slide instead of clinging to the top and
   leaving the bottom half empty; tall content simply fills the space.
   Don't add a fixed margin-top back on top of this class. */
.slide-body { margin-top: auto; margin-bottom: auto; width: 100%; min-height: 0; }

/* Bulleted points (square markers, never decorative dots) */
:where(.points) { margin: 0; }
.points { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 36px; }
.points > li {
  display: flex; gap: 24px;
  font: var(--fw-regular) var(--fs-slide-body)/1.6 var(--font-sans); color: var(--text-body);
}
.points > li::before {
  content: ""; flex-shrink: 0; width: 14px; height: 14px; margin-top: 16px;
  border-radius: 3px; background: var(--brand);
}
.points > li b, .points > li strong { font-weight: var(--fw-bold); color: var(--text-strong); }
/* Emphasis phrases never break mid-bold — the whole run stays on one line and
   the wrap happens before/after it. Keep bold to a SHORT claim so it can't
   overflow the measure; never put a <budoux-ja> (U+200B) inside a bold run. */
.slide b, .slide strong, .emph { white-space: nowrap; }
.points .sub { display: block; margin-top: 10px; font-size: var(--fs-slide-sub); color: var(--text-muted); line-height: 1.6; }

/* Two-column / comparison */
.cols-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: start; }
.cols-2--rule { position: relative; }
.cols-2--rule::after { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--border-subtle); }

/* Numbered agenda list */
:where(.agenda) { margin: 0; }
.agenda { list-style: none; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 40px 72px; }
.agenda > li { display: flex; align-items: baseline; gap: 22px; font: var(--fw-medium) 36px/1.4 var(--font-sans); color: var(--text-strong); }
.agenda > li .no { font: var(--fw-bold) 28px var(--font-mono); color: var(--blue-900); font-variant-numeric: tabular-nums; min-width: 50px; }
.agenda > li .desc { display: block; margin-top: 8px; font: var(--fw-regular) 24px var(--font-sans); color: var(--text-muted); }

/* Big stat — one number that makes the point */
.stat-row { display: flex; gap: 100px; flex-wrap: wrap; align-items: flex-end; }
.stat .stat-label { font: var(--fw-medium) var(--fs-slide-sub) var(--font-sans); color: var(--text-muted); }
.stat .stat-value {
  display: flex; align-items: baseline; gap: 12px; margin-top: 14px;
  font: var(--fw-bold) var(--fs-slide-stat)/1 var(--font-sans); color: var(--text-strong);
  letter-spacing: var(--ls-tight); font-variant-numeric: tabular-nums;
}
.stat .stat-value .unit { font-size: 44px; font-weight: var(--fw-medium); color: var(--text-muted); }
.stat .stat-note { margin-top: 18px; font: var(--fw-regular) var(--fs-slide-sub) var(--font-sans); color: var(--text-subtle); }
.stat--accent .stat-value { color: var(--brand-strong); }

/* Figure / chart frame */
.figure {
  background: var(--surface-card); border: 1px solid var(--border-default);
  border-radius: var(--radius-md); box-shadow: var(--shadow-card);
  padding: 32px; box-sizing: border-box;
}
.figure-title { font: var(--fw-bold) 30px var(--font-sans); color: var(--text-strong); margin: 0 0 4px; }
.figure-title .dt { font-weight: var(--fw-regular); font-size: 22px; color: var(--text-muted); }
.figure-ph {
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-page); border: 1px solid var(--border-subtle);
  border-radius: var(--radius-sm); color: var(--text-subtle);
  font: var(--fw-medium) 20px var(--font-sans);
}

/* Code slide — Consolas only place permitted */
.code-block {
  background: var(--gray-900); color: #EDEDF2;
  border-radius: var(--radius-md); padding: 40px 44px;
  font: var(--fw-regular) 28px/1.7 var(--font-mono);
  overflow: auto; tab-size: 2;
}
.code-block .c-key { color: #7AB8FF; }
.code-block .c-str { color: #9BD4B5; }
.code-block .c-com { color: #9A9AA6; }
.code-block .c-fn  { color: #FFC700; }

/* Do / Don't */
.dodont { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; }
.dodont .col { border: 1px solid var(--border-default); border-radius: var(--radius-md); overflow: hidden; display: flex; flex-direction: column; }
.dodont .col > header { display: flex; align-items: center; gap: 14px; padding: 26px 36px; font: var(--fw-bold) 32px var(--font-sans); color: #fff; }
.dodont .do > header { background: var(--success); }
.dodont .dont > header { background: var(--negative); }
.dodont .col .badge { width: 40px; height: 40px; border-radius: 50%; background: rgba(255,255,255,0.25); display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 700; }
.dodont .col p { margin: 0 36px 36px; font: var(--fw-regular) 26px/1.65 var(--font-sans); color: var(--text-body); }
.dodont .col .figure-ph { margin: 36px; flex: 1; min-height: 240px; font-size: 22px; }

/* Section divider */
.slide--section { background: var(--blue-50); display: flex; flex-direction: column; justify-content: center; }
.slide--section .slide-kicker { font-size: 30px; }
.slide--section .slide-title { font-size: var(--fs-slide-title-lg); }
.slide--section .slide-lead { font-size: 30px; margin-top: 28px; }

/* ---- In-deck variant (deck_stage sizes/positions each section itself,
   so .dslide must NOT set width/height/position) ---- */
.dslide {
  position: relative;
  background: var(--surface-card);
  color: var(--text-body);
  font-family: var(--font-sans);
  box-sizing: border-box;
  padding: var(--slide-margin-y) var(--slide-margin-x);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  /* height comes from the deck-stage host's ::slotted(*) rule
     (position/inset/width/height: 100% !important) — don't set it here. */
}

/* Closing */
.slide--closing { background: var(--brand-strong); color: #fff; display: flex; flex-direction: column; justify-content: center; }
.slide--closing .slide-title { color: #fff; font-size: 88px; }
.slide--closing .slide-lead { color: rgba(255,255,255,0.82); font-size: 30px; }

/* ============================================================
   IMAGE PLACEMENT — photos/screenshots go directly on the slide.
   Never wrap a photo in a shadowed, rounded "card" — the guidebook's
   flat, restrained surface language (§ VISUAL FOUNDATIONS) applies to
   photos too, and a card box sized for text will crop or spill the
   image. Pick by JOB, not by which one looks fanciest:

   .content-img   DEFAULT for an explanatory slide. Text carries the
                  argument (points, real body copy); the image is
                  supporting reference material and stays modest —
                  contained, no bleed, no chrome. Reach for this first
                  whenever a slide needs both real text and a photo.
   .slide-img--center  the image itself IS the whole point of the
                  slide (e.g. one screenshot slide) — large, centered,
                  little/no body copy. object-fit:contain guarantees it
                  scales DOWN to fit and never overflows — no card.
   .slide-img--full    a flashy, high-impact moment — a section break
                  or cover — NOT a place to explain something. Image
                  edge-to-edge; a flat caption band (no gradient scrim)
                  carries the title. Use sparingly, once or twice a deck.
   .slide-img--split    same spirit as full bleed — a stylish divider —
                  but half the slide can carry a short lead-in line.
                  Still not for dense explanation; use `.content-img`
                  for that even when a photo is involved.
   .img-compare   TWO images placed side by side to CONTRAST them
                  (before/after, option A vs B, two screenshots). Each
                  column is a heading + a directly-placed image + a
                  caption, split by a center rule — the image analogue
                  of `.cols-2--rule`. For text-vs-text comparison use
                  `.cols-2--rule`; for one dominant image use
                  `.slide-img--center`.

   NOTE — sizing SVGs / vector figures. Use the `.figure-box` +
   `.figure-svg` helper (defined below) instead of hand-writing a
   width hack. It fixes the two traps that bite:
   (1) an EXPORTED SVG with a fixed inch size on its root
       (`width="6in"`) won't scale past its small intrinsic size under
       `max-height`/`max-width` — via `<img>` even `width:100%` can
       fail; if so, delete the root width/height and let `viewBox`
       govern; and
   (2) a bare `display:flex; justify-content:center` wrapper is
       shrink-to-fit, so `width:100%` collapses back to intrinsic —
       the wrapper needs a real width. Full mechanics live on the
       `.figure-box`/`.figure-svg` rules below.
   ============================================================ */

/* ---- Content + supporting image: text-heavy explanation with a
   smaller reference image alongside. The image is placed directly
   (no border/shadow/radius) and never crops — same discipline as the
   other patterns, just modest instead of dominant. ---- */
.content-img { display: grid; grid-template-columns: 1.3fr 1fr; gap: 64px; align-items: center; }
.content-img__figure { display: flex; flex-direction: column; align-items: center; gap: 20px; }
.content-img__figure img { display: block; width: 100%; max-height: 480px; object-fit: contain; }
.content-img__figure .cap { font: var(--fw-regular) 20px var(--font-sans); color: var(--text-subtle); text-align: center; }

/* ---- Image comparison: two figures side by side to CONTRAST two
   visuals (before/after, option A/B). Each column is a left-aligned
   heading + a directly-placed, contained image (no card/shadow/radius,
   never crops) + a left-aligned caption, split by a 1px center rule.
   The image counterpart of `.cols-2--rule`. ---- */
.img-compare { display: grid; grid-template-columns: 1fr 1fr; gap: 72px; align-items: start; position: relative; }
.img-compare::after { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 1px; background: var(--border-subtle); }
.img-compare__col { display: flex; flex-direction: column; align-items: stretch; gap: 24px; min-width: 0; }
.img-compare__head { margin: 0; font: var(--fw-bold) 32px var(--font-sans); color: var(--text-strong); }
.img-compare__head--accent { color: var(--blue-900); }
/* width:100% so unit-sized SVGs scale UP to the column; max-height only caps */
.img-compare__col img { display: block; width: 100%; max-height: 540px; object-fit: contain; }
.img-compare__cap { margin: 0; font: var(--fw-regular) 22px/1.5 var(--font-sans); color: var(--text-subtle); text-wrap: pretty; }

/* ---- Vector-figure helper (.figure-box + .figure-svg) -------------------
   Makes an SVG / exported diagram FILL its column regardless of the file's
   own intrinsic size, so authors stop hand-writing a width hack per figure.
   Wrap the figure in .figure-box and put .figure-svg on the <img>/<svg>.

   Solves the two traps that actually bit us:
   1) EXPORTED SVG WITH A FIXED INCH SIZE (Fritzing etc.). A root
      `width="6in" height="4in"` gives a small intrinsic size that
      max-width/max-height — and, via <img>, even width:100% — can't grow
      past. .figure-svg forces `width:100%` (CSS beats an inline <svg>'s
      presentation width/height attributes). If it is referenced as
      `<img src="*.svg">` and STILL won't scale, open the file and delete
      the root width/height so only `viewBox` remains — then it has no fixed
      intrinsic size and stretches freely.
   2) SHRINK-TO-FIT CENTERING WRAPPER. In a bare
      `display:flex; justify-content:center`, width:100% on the image
      resolves against a parent that collapsed to its content, so the image
      snaps back to intrinsic. .figure-box carries a real width (100%), so
      width:100% has a full-width box to resolve against.
   To cap AND stay proportional, set a `max-width` on .figure-box (that
   shrinks both dimensions and margin-inline:auto keeps it centered) —
   don't cap with height, which either letterboxes an <img> or distorts an
   inline <svg>. ---- */
.figure-box { width: 100%; margin-inline: auto; }
.figure-svg { display: block; width: 100%; height: auto; object-fit: contain; }

/* ---- Center: large image inside the normal content area ---- */
.slide-img--center {
  flex: 1 1 auto;
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  width: 100%;
}
.slide-img--center img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
.slide-img--caption {
  flex-shrink: 0;
  margin-top: 28px;
  font: var(--fw-regular) 22px var(--font-sans);
  color: var(--text-subtle);
  text-align: center;
}

/* ---- Full bleed: image fills the whole slide ---- */
.slide--img-full { padding: 0; }
.slide-img--full-frame { flex: 1 1 auto; min-height: 0; overflow: hidden; }
.slide-img--full-frame img { display: block; width: 100%; height: 100%; object-fit: cover; }
.slide-img--full-caption {
  flex-shrink: 0;
  background: var(--surface-card);
  border-top: 6px solid var(--brand);
  padding: 40px var(--slide-margin-x) 44px;
}
.slide-img--full-caption .slide-kicker { margin: 0 0 8px; }
.slide-img--full-caption .slide-title { margin: 0; }

/* ---- Split: image bleeds one half, text keeps the other ---- */
.slide--img-split { padding: 0; flex-direction: row; }
.slide-img--split { flex: 1 1 50%; min-width: 0; overflow: hidden; align-self: stretch; }
.slide-img--split img { display: block; width: 100%; height: 100%; object-fit: cover; }
.slide--img-split .slide-content {
  flex: 1 1 50%; min-width: 0;
  box-sizing: border-box;
  padding: var(--slide-margin-y) var(--slide-margin-x);
  display: flex; flex-direction: column;
}
.slide--img-split.is-img-right { flex-direction: row; }
.slide--img-split.is-img-left { flex-direction: row-reverse; }
