/*
 * The front page.
 *
 * Loaded after site.css, scoped under `.home` on <body>, and site.css is never
 * edited: ten hand-written pages, the monthly reports and the ward pages all
 * share it, so a change there has a blast radius this page does not need.
 * `.home .site-nav` at 0,2,0 beats `.site-nav` at 0,1,0 with no !important.
 *
 * Widths, in order of how much room they take:
 *   .home-bleed / section itself   edge to edge, no padding
 *   .home-gutter                   NO max-width, gutter padding only
 *   .home-shell                    1200px, used by nothing but prose
 * Never 100vw and never calc(50% - 50vw). `body { overflow-x: hidden }` in
 * site.css would hide the resulting overflow rather than surface it, and the
 * repo's own idiom is structural: a block child of an unconstrained parent.
 */

.home {
  --home-nav-h: 68px;
  --home-band-space: clamp(3.5rem, 7vw, 7rem);
  --home-rule: var(--border);
  /* How much of the window the graphic side may take. The hero's type track is
   * whatever is left, so this figure sizes the headline too (see .home-hero h1)
   * and the two must be read together. */
  --home-map-max: 50vw;
}

@media (max-width: 1180px) {
  .home {
    --home-nav-h: 56px;
  }
}

@media (max-width: 820px) {
  .home {
    --home-nav-h: 58px;
  }
}

/*
 * Gutter to gutter, with one ceiling far above any normal monitor.
 *
 * No cap at all was the point: the page must not read as a 1200px box floating
 * in margins. But past ~2000px the opposite goes wrong, and a narrow city like
 * Kyoto ends up with a thousand pixels of nothing between the type and the map.
 * 2000px is above every common width (1440, 1680, 1920 are untouched) and only
 * bites on ultra-wide displays.
 */
.home-gutter {
  width: min(2000px, 100%);
  margin: 0 auto;
  padding: 0 var(--page-gutter);
}

.home-shell {
  width: min(1200px, 100%);
  margin: 0 auto;
  padding: 0 var(--page-gutter);
}

/*
 * Japanese never renders bold: at UI sizes the strokes of a kanji merge and the
 * character stops being readable. site.css still sets weights up to 800 on
 * headings, the nav brand and the footer. Hierarchy is size, colour and space.
 */
.home:lang(ja),
.home:lang(ja) * {
  font-weight: 400 !important;
}

/* Digits stay legible at medium weight, and these are numeric only. */
.home:lang(ja) .home-figure-value,
.home:lang(ja) .home-readout-value,
.home:lang(ja) .home-pill {
  font-weight: 500 !important;
}

/* site.css sets scroll-behavior: smooth, and the sticky nav eats anchor targets. */
.home [id] {
  scroll-margin-top: calc(var(--home-nav-h) + 1rem);
}

/* ---------- nav ---------- */

/* Full width. Everything else about the nav, including the checkbox-driven
 * mobile menu, is left exactly as site.css has it. */
.home .site-nav .nav-inner {
  width: 100%;
}

/*
 * Clear over the hero, opt-in via a class.
 *
 * Opt-in rather than opt-out on purpose: with JS blocked the class is never
 * added and the nav stays solid, which is the safe state. The inverse would
 * leave a permanently transparent bar with content scrolling under it. Gated
 * above the mobile breakpoint so it never applies while the dropdown panel is
 * in play.
 */
@media (min-width: 821px) {
  .home.is-over-hero .site-nav {
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    box-shadow: none;
  }
}

/*
 * The closed mobile menu must not take taps.
 *
 * site.css hides the drop panel with `opacity: 0; visibility: hidden`, and then,
 * inside the same media query, sets `visibility: visible` on `.nav-menu` so the
 * product/uses/trust groups sit open once the panel is showing. Visibility is
 * inherited, so a descendant turning it back on un-hides that subtree for
 * hit-testing while the panel is still closed, and `opacity: 0` has never
 * stopped pointer events. The result is a stack of invisible nav links floating
 * across the middle of the page, swallowing taps meant for whatever is under
 * them.
 *
 * Killing pointer events while the checkbox is unchecked fixes it without
 * touching the visibility dance, and cannot affect the open menu.
 *
 * This is a site.css bug and it is on every page that renders this nav, not just
 * this one. Scoped here because site.css is not edited from this page.
 */
@media (max-width: 820px) {
  .home .site-nav .nav-links {
    pointer-events: none;
  }

  .home .site-nav .nav-toggle:checked ~ .nav-inner .nav-links {
    pointer-events: auto;
  }
}

/* ---------- hero ---------- */

.home-hero {
  position: relative;
  display: grid;
  /*
   * The map column is sized by the map, not by a fraction.
   *
   * City outlines differ wildly in shape: Tokyo is square, Kyoto is 0.59 wide,
   * Kawasaki 1.64. A fractional column reserves the same width for all of them,
   * so a tall city left hundreds of pixels of reserved-but-empty space beside
   * itself on a wide screen. `auto` collapses the column onto the drawing, and
   * the type track takes what is left.
   */
  grid-template-columns: minmax(0, 1fr) auto;
  width: min(2000px, 100%);
  margin: 0 auto;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  min-height: calc(100svh - var(--home-nav-h));
  padding: clamp(1.5rem, 4vw, 3rem) 0 clamp(2rem, 5vw, 4rem);
  border-bottom: 1px solid var(--home-rule);
}

/*
 * The type takes the track it is given.
 *
 * This block used to stop at 46rem inside a track roughly a thousand pixels
 * wide, so the page opened with the words pinned to the left edge and a band of
 * nothing before the map. The cap is still a cap (a 2000px screen must not set
 * a 1200px measure), it is just no longer narrower than the column it sits in.
 */
.home-hero-type {
  padding-left: var(--page-gutter);
  max-width: 58rem;
  /*
   * Top of the row, not the middle of it.
   *
   * The map is a viewport tall, so centring this block against it put the
   * headline a third of the way down the screen with nothing above it. The
   * column now starts where the page starts and runs down: headline, lede,
   * readout, ramp, actions, then the coverage figures at its foot.
   */
  align-self: start;
  padding-top: clamp(1rem, 4vh, 3.5rem);
}

/*
 * Sized off the track it sits in, not off the window.
 *
 * The renderer emits the headline as whole phrases and the longest is 9
 * full-width characters, so the type must fit 9em. A plain vw size does not
 * know that the graphic took half the window: at 1280px a 4.4vw headline needed
 * 507px in a 450px track and broke "町丁目までわかる。" across two lines, mid
 * phrase, which is exactly what .home-h1-line exists to prevent. The track is
 * the window less the graphic side less its gaps and gutter (~12rem), so a
 * ninth of that is the largest size that always fits. English's longest line is
 * around 17 latin characters, which is the same 9em, so it takes the same rule.
 */
.home-hero h1 {
  font-size: clamp(2rem, calc((100vw - var(--home-map-max) - 12rem) / 9), 4rem);
  line-height: 1.15;
  letter-spacing: -0.03em;
}

/* Japanese has no spaces, so a browser given one long heading breaks it inside
 * a word. The renderer emits phrases; these keep each one whole. */
.home-h1-line {
  display: block;
}

.home-hero-lede {
  margin-top: 1.5rem;
  max-width: 38rem;
  color: var(--muted-strong);
  font-size: clamp(1rem, 1.3vw, 1.125rem);
  line-height: 1.8;
}

/* ---------- hero map ---------- */

/*
 * The city rail and the drawing travel together.
 *
 * They are one grid child rather than two so the hero keeps a single large gap
 * between the words and the graphic, while the rail sits close to the map it
 * acts on. Two grid columns would have put that same large gap on both sides of
 * a rail one word wide.
 */
.home-hero-view {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2vw, 2rem);
  justify-self: end;
  min-width: 0;
}

/*
 * A fixed box, not a box that fits the drawing.
 *
 * Two reasons, and the first is the one that decided it. Sized to its contents,
 * this figure was as wide as whichever city was loaded, so the rail beside it
 * moved every time the city changed: the control you just clicked jumped out
 * from under the pointer, and Kyoto's rail and Kawasaki's rail sat 200px apart.
 * A navigation element has to stay where it is. Second, the caption is a full
 * sentence, and `auto` grid tracks size to max-content, so unconstrained it
 * asked for its whole length on one line and squeezed the type track to a couple
 * of hundred pixels at 1000px.
 *
 * The cost is honest: a narrow city (Kyoto is 0.59 as wide as it is tall) leaves
 * space between the rail and its outline. That is the price of the rail holding
 * still, and it is worth paying.
 */
.home-hero-map {
  margin: 0;
  /* Hard against the right viewport edge: no gutter, nothing after it. */
  padding: 0;
  width: var(--home-map-max);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
}

/*
 * Height-driven, so the drawing decides its own width from its aspect.
 * Width-driven sizing (width:100%, height:auto) makes a tall city letterbox
 * inside a box far wider than the shape, which is where the empty space came
 * from. The cap keeps a wide city (Kawasaki) from crowding the type.
 */
.home-map-svg {
  display: block;
  /* Height-bound only. Capping this in rem left a tall screen showing a small
   * map beside a wide band of nothing; letting it use the viewport height means
   * the drawing grows into the space instead of the space staying empty. */
  height: calc(100svh - var(--home-nav-h) - 9rem);
  width: auto;
  max-width: var(--home-map-max);
}

/*
 * The city assembles, ward by ward, west to east.
 *
 * Each path carries its own rank in `--i` (the renderer computes it from the
 * shape's mean x) and turns it into a delay, so the drawing arrives as a
 * composition of its parts rather than appearing whole. 30ms a ward puts a
 * 24-ward city under 0.9s end to end, which is the ceiling worth spending here:
 * the map is the LCP element and every millisecond of this is paid for.
 *
 * Applied to the element, not to a class, so it runs in both cases that matter:
 * the inline map at parse time, and a fetched city, where innerHTML makes new
 * nodes and the animation starts again with no help from the script.
 */
.home-map-shapes path {
  stroke: #fff;
  stroke-width: 0.5;
  stroke-linejoin: round;
  animation: home-map-in 380ms ease-out backwards;
  animation-delay: calc(var(--i, 0) * 30ms);
}

@keyframes home-map-in {
  from {
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .home-map-shapes path {
    animation: none;
  }
}

.home-map-shapes path:hover {
  stroke: var(--text);
  stroke-width: 1.5;
  cursor: pointer;
}

.home-map-note {
  margin-top: 0.875rem;
  padding-right: var(--page-gutter);
  color: var(--muted);
  font-size: 0.75rem;
  line-height: 1.7;
  text-align: right;
}

/* ---------- readout and ramp ---------- */

.home-readout {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.25rem 0.75rem;
  min-height: 3.25rem;
  margin-top: 2rem;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border-strong);
}

.home-readout-idle {
  color: var(--muted);
  font-size: 0.875rem;
}

.home-readout-name {
  font-size: 1.125rem;
}

.home-readout-value {
  font-size: 1.5rem;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.home-readout-sub {
  color: var(--muted);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.home-ramp {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  margin-top: 0.875rem;
  color: var(--muted);
  font-size: 0.75rem;
}

.home-ramp-bar {
  display: flex;
  flex: 1;
  max-width: 24rem;
  height: 0.5rem;
}

.home-ramp-bar i {
  flex: 1;
}

/* ---------- city rail and actions ---------- */

/*
 * The city switch, stacked against the map.
 *
 * Nine names in a row under the type wrapped onto two lines, sat below the
 * actions, and were a long way from the only thing they change. As a column on
 * the map's left edge they read as an index, never wrap however many cities are
 * added, and the choice is next to its result. The rule is the page's own
 * hairline; the active city thickens the segment beside its name, which is the
 * underlined tab turned on its side.
 */
.home-cities {
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--border);
  font-size: 0.875rem;
  text-align: right;
}

.home-tab {
  padding: 0.4375rem 0.875rem 0.4375rem 0;
  /* Pulls the 2px marker over the container's 1px rule so both right edges sit
   * on the same pixel and the hairline never doubles. */
  margin-right: -1px;
  border-right: 2px solid transparent;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  transition:
    color 0.15s ease,
    border-color 0.15s ease;
}

.home-tab:hover {
  color: var(--text);
}

.home-tab.is-active {
  color: var(--text);
  border-right-color: var(--text);
}

.home-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem 1.75rem;
  margin-top: 1.75rem;
}

/*
 * Outlined, never filled, and never inverted on hover.
 *
 * The old hover flooded the button with near-black and flipped the label to
 * white, which is the loudest thing on a page whose entire palette is paper and
 * ink. Hover now moves the same two properties the rest of the page moves: the
 * rule darkens to full text colour and the face takes the paper tint. Nothing
 * changes colour, it only firms up.
 */
.home-button {
  display: inline-block;
  padding: 0.6875rem 1.375rem;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  color: var(--text);
  font-size: 0.9375rem;
  text-decoration: none;
  transition:
    background-color 0.15s ease,
    border-color 0.15s ease;
}

.home-button:hover {
  background: var(--paper);
  border-color: var(--text);
}

.home-button--quiet {
  color: var(--muted-strong);
}

/*
 * The second action is not a second button.
 *
 * Two identically outlined boxes side by side read as a consumer call-to-action
 * pair and say neither of them is the one to take. One box, one link.
 */
.home-link {
  color: var(--muted-strong);
  font-size: 0.9375rem;
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 0.35em;
  transition:
    color 0.15s ease,
    text-decoration-color 0.15s ease;
}

.home-link:hover {
  color: var(--text);
  text-decoration-color: var(--text);
}

.home-hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.5rem;
  margin-top: 1.25rem;
  color: var(--muted);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

[data-nav-sentinel] {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
}

/* ---------- bands ---------- */

.home-band {
  padding: var(--home-band-space) 0;
  border-bottom: 1px solid var(--home-rule);
}

/*
 * No tinted section backgrounds.
 *
 * The page used to alternate white and --paper down its length to mark where
 * one section ended and the next began. It read as banding: a stripe of colour
 * that carries no information, changes the meaning of nothing on either side of
 * it, and is the first thing that dates a page. Sections are separated by the
 * rule below them and by having genuinely different shapes.
 */

.home-band--rule {
  padding: clamp(2.5rem, 4vw, 3.5rem) 0;
}

.home-section-title,
.home-section-head h2,
.home-band h2 {
  font-size: clamp(1.5rem, 2.6vw, 2.25rem);
  line-height: 1.3;
  letter-spacing: -0.02em;
}

.home-lede {
  margin-top: 0.875rem;
  max-width: 42rem;
  color: var(--muted-strong);
  line-height: 1.8;
}

.home-section-head {
  margin-bottom: clamp(2rem, 3.5vw, 3rem);
}

/* ---------- coverage figures + ward index ---------- */

/*
 * Figures separated by space, not by rules.
 *
 * A ruled four-cell row was tried and read as a table someone forgot to finish.
 * The figures are already distinct because they are large and their labels are
 * small; a vertical hairline between them adds nothing but furniture.
 *
 * Two per row rather than one long line: these sit in the hero's type column
 * now, which is half the page, and four of them abreast there would each get
 * about a hundred pixels. The pair grid also keeps the four labels on a common
 * left edge, which a wrapping flex row does not.
 */
.home-figures {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: 1.25rem clamp(1.5rem, 3vw, 3rem);
  margin: 1.75rem 0 0;
  padding: 0;
  list-style: none;
}

.home-figures li {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.375rem;
}

.home-figure {
  display: flex;
  align-items: baseline;
  gap: 0.25rem;
}

.home-figure-value {
  font-size: clamp(1.5rem, 2.4vw, 2.125rem);
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.home-figure-unit {
  color: var(--muted);
  font-size: 0.875rem;
}

.home-figure-label {
  color: var(--muted);
  font-size: 0.875rem;
  line-height: 1.5;
}

/* Last block in the hero column. No rule above it and no band spacing: the
 * figures, the index and the type are one column of one thing, and a divider
 * between them would claim they are separate sections. */
.home-ward-index {
  margin-top: 3.5rem;
}

.home-ward-index h2 {
  font-size: 0.8125rem;
  letter-spacing: 0.08em;
  color: var(--muted);
}

/* Narrow columns, because 23 ward names now sit in half the page rather than
 * across it. minmax(7rem) left four wide columns with the names lost in them. */
.home-ward-index ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
  gap: 0.4375rem 1.25rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.875rem;
}

.home-ward-index a {
  text-decoration: none;
  color: var(--muted-strong);
}

.home-ward-index a:hover {
  color: var(--accent-dark);
}

/* ---------- nationwide ---------- */

/*
 * Copy first, map second, and the map takes the width.
 *
 * The old split was a small map beside a heading and a 22-name list, which said
 * the same thing three times. The list is gone: the names are on the map, where
 * they can also carry a figure.
 */
/*
 * Map left, the reading of it right.
 *
 * The map alone was a stamp centred in a wide column with white down both
 * sides. It is an index, not an illustration, so it now sits beside the thing it
 * indexes and the two are wired together: pointing at a row lights its city, and
 * pointing at a city lights its row.
 */
.home-nation {
  display: grid;
  grid-template-columns: auto minmax(0, max-content);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  /*
   * Centred as a pair, not stretched across the gutter.
   *
   * The panel used to be a 1fr track holding a table capped well under it, so
   * on a wide screen every pixel of slack piled up on the right and the section
   * read as half-finished. Sizing the panel to its content and centring the two
   * puts the same slack on both sides, where it looks like margin.
   */
  justify-content: center;
  align-items: start;
}

.home-nation-panel {
  min-width: 0;
}

.home-nation-hint {
  color: var(--muted);
  font-size: 0.8125rem;
}

/*
 * Shrunk to the drawing, because the card is positioned against this box.
 *
 * setUpNation places the card in percentages of the SVG's viewBox. That only
 * lands on the pin if this element IS the SVG's box: when it was a full-width
 * column with a narrower drawing centred inside it, every card sat left of the
 * dot it belonged to by half the leftover space.
 */
.home-nation-map {
  position: relative;
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
}

/* Height-capped, so the section is a section and not a page of its own: Japan
 * is a tall drawing and at full column width it ran past a viewport. */
.home-nation-map svg {
  display: block;
  width: auto;
  max-width: 100%;
  height: min(72svh, 40rem);
  margin: 0 auto;
  overflow: visible;
}

/*
 * The land is background now, not the claim.
 *
 * Prefectures used to be tinted to say where we work, which put a hard green
 * edge on a boundary nobody asked about: coverage is a city, and a prefecture is
 * only the shape it happens to sit in. Uniform, quiet land, with the claim made
 * by the pins on top of it.
 */
.home-nation-land path {
  fill: #f2f0ea;
  stroke: #ffffff;
  stroke-width: 0.6;
}

/* The map takes the pointer, not the dots: setUpNation resolves the nearest
 * city itself, because the dots overlap in Kansai and Kanto. */
.home-nation-map svg {
  cursor: default;
}

/*
 * Grown with a transform, not by animating `r`.
 *
 * `r` is a CSS geometry property and Firefox does not honour it, so a rule that
 * sets it on hover simply does nothing there. transform-box: fill-box makes the
 * scale happen about the dot's own centre rather than the SVG's origin, which is
 * what sends an un-boxed transform flying off the map.
 */
.home-pin-dot {
  fill: var(--accent-dark, #2f6b46);
  stroke: #ffffff;
  stroke-width: 1.1;
  transform-box: fill-box;
  transform-origin: center;
  transition:
    transform 0.15s ease,
    fill 0.15s ease;
}

.home-pin:hover .home-pin-dot,
.home-pin.is-on .home-pin-dot,
.home-pin:focus-visible .home-pin-dot {
  transform: scale(1.6);
  fill: var(--text);
}

.home-pin:focus {
  outline: none;
}

.home-pin:focus-visible .home-pin-dot {
  stroke: var(--text);
}

@media (prefers-reduced-motion: reduce) {
  .home-pin-dot {
    transition: none;
  }
}

/*
 * The readout, as a card that hangs off its pin.
 *
 * Positioned in percentages of the map box (see setUpNation) and lifted clear of
 * the dot, with modifiers to flip it when the pin is near an edge. Rounded and
 * shadowed on purpose: it floats above the drawing and has to read as a layer
 * over it rather than as part of it.
 */
.home-pin-card {
  position: absolute;
  z-index: 2;
  transform: translate(-50%, calc(-100% - 0.75rem));
  display: grid;
  gap: 0.125rem;
  min-width: 8.5rem;
  padding: 0.625rem 0.875rem;
  background: #ffffff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(26, 25, 23, 0.12);
  pointer-events: none;
  white-space: nowrap;
}

/*
 * The attribute has to win here.
 *
 * `hidden` is a UA rule (`[hidden] { display: none }`) and the `display: grid`
 * above outranks it, so setting card.hidden = true did nothing at all and the
 * card, once shown, never went away.
 */
.home-pin-card[hidden] {
  display: none;
}

.home-pin-card.is-below {
  transform: translate(-50%, 0.75rem);
}

.home-pin-card.is-left {
  transform: translate(-100%, calc(-100% - 0.75rem));
}

.home-pin-card.is-left.is-below {
  transform: translate(-100%, 0.75rem);
}

.home-pin-city {
  font-size: 0.9375rem;
}

.home-pin-areas {
  color: var(--muted-strong);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.home-pin-go {
  margin-top: 0.25rem;
  color: var(--muted);
  font-size: 0.75rem;
}

/* ---------- three answers, as rows ---------- */

/*
 * A ledger you read down, not three cards side by side.
 *
 * Copy left, the proof in the middle, and one word right, large enough to be the
 * thing you actually see. The screenshot is only offered on hover, so at rest
 * the section is three lines of type and a word each: the reader scans "予算,
 * 沿線, 割高" in a second and asks for the picture of whichever one is theirs.
 */
.home-answers {
  margin: clamp(2rem, 3.5vw, 3rem) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--border);
}

.home-answers li {
  border-bottom: 1px solid var(--border);
}

/*
 * The middle track is a fixed width, and that is the point of it.
 *
 * With `auto` on the word column, each row's word sized its own track (Budget,
 * Rail, Overpriced are nothing like the same width), so the middle column came
 * out a different width in each row and the screenshot landed at a different x
 * every time. Pinning the shot's track makes the three images line up, and the
 * word column absorbs the difference where nobody can see it.
 */
.home-answer {
  display: grid;
  /* Equal side tracks, fixed centre: the shot sits on the row's midline rather
   * than wherever the copy and the word happen to leave it. */
  grid-template-columns: minmax(0, 1fr) clamp(15rem, 26vw, 30rem) minmax(0, 1fr);
  align-items: center;
  gap: clamp(1.5rem, 3.5vw, 3.5rem);
  padding: clamp(1.75rem, 3vw, 2.75rem) clamp(1rem, 3.5vw, 3.5rem);
  color: inherit;
  text-decoration: none;
  transition: background-color 0.2s ease;
}

.home-answer:hover {
  background: var(--paper);
}

.home-answer-copy {
  display: grid;
  gap: 0.5rem;
  /* The track is now half of what is left over, which is wider than a column of
   * text should be. */
  max-width: 22rem;
}

.home-answer-index {
  color: var(--muted);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
}

.home-answer-title {
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  line-height: 1.45;
}

.home-answer:hover .home-answer-title {
  text-decoration: underline;
  text-underline-offset: 0.3em;
  text-decoration-color: var(--border-strong);
}

.home-answer-body {
  color: var(--muted-strong);
  font-size: 0.9375rem;
  line-height: 1.75;
}

/*
 * The slot keeps its height whether or not the shot is showing.
 *
 * The image is portrait and tall, so it is contained rather than cropped, and
 * the slot is the thing with the height. Sizing the row to the image instead
 * would make every hover shove the rows below it down the page.
 */
/*
 * The slot keeps its size whether or not the shot is showing.
 *
 * Held at 16:9 by the aspect ratio rather than by the image, so the row height
 * is the same before the image has loaded and the same on the row that is not
 * being pointed at. Sizing the row to the image instead would make every hover
 * shove the rows below it down the page.
 */
.home-answer-shot {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity 0.25s ease,
    transform 0.25s ease;
}

.home-answer-shot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 1px solid var(--border);
}

.home-answer:hover .home-answer-shot,
.home-answer:focus-visible .home-answer-shot {
  opacity: 1;
  transform: none;
}

/*
 * The word, at the size of the thing it names.
 *
 * Japanese never goes bold here, so the weight stays 400 and the size does the
 * work; at this scale that reads as deliberate rather than shouted. It is
 * aria-hidden because the row already has its real title above.
 */
.home-answer-word {
  justify-self: end;
  font-size: clamp(2rem, 3.8vw, 4rem);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--text);
  white-space: nowrap;
  transition: color 0.2s ease;
}

.home:lang(en) .home-answer-word {
  font-weight: 500;
}

.home-answer:hover .home-answer-word {
  color: var(--accent-dark);
}

/* No hover to give: show the proof rather than hiding it behind a gesture that
 * does not exist. */
@media (hover: none) {
  .home-answer-shot {
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .home-answer-shot {
    transition: none;
    transform: none;
  }
}

/* ---------- coverage table (the old market section, merged in) ---------- */

/*
 * Airy, not ruled to death.
 *
 * A hairline under every row turns nine rows into nine boxes and makes the eye
 * stop at each one. One rule under the header, generous row height, and a soft
 * rounded band on hover: the row is found by pointing at it rather than by being
 * fenced. The figures do the structural work, which is why they are all tabular.
 */
/*
 * The table scrolls rather than pushing the page sideways.
 *
 * Its cells are nowrap (six columns of figures must not break mid-number), so
 * its min-content width is around 700px and no grid track can squeeze it below
 * that. Without this the whole document scrolled horizontally on a phone, and
 * site.css's `body { overflow-x: hidden }` would have swallowed the evidence
 * instead of showing it.
 */
.home-coverage-scroll {
  max-width: 100%;
  overflow-x: auto;
}

.home-coverage {
  width: 100%;
  /* Wide enough to carry six columns without them drifting apart, capped so it
   * never becomes a row of figures a screen wide. */
  max-width: 58rem;
  min-width: 0;
  margin-top: clamp(1.25rem, 2.5vw, 1.75rem);
  border-collapse: separate;
  border-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/*
 * Undo site.css's report-table styling, which this inherits by element.
 *
 * That sheet dresses every `table` for the monthly reports: a 720px min-width
 * (which quietly beat the max-width above, so the table stayed as wide as it
 * ever was), a tinted `th` background that painted a grey stripe down the city
 * column, uppercase letter-spaced headers, and a border on every cell.
 */
.home-coverage th,
.home-coverage td {
  padding: 0.6875rem 0.875rem;
  border-bottom: 0;
  background: none;
  color: inherit;
  font-size: 0.9375rem;
  letter-spacing: normal;
  text-align: left;
  text-transform: none;
  vertical-align: middle;
  white-space: nowrap;
}

.home-coverage th:first-child,
.home-coverage td:first-child {
  padding-left: 0.625rem;
}

.home-coverage th:last-child,
.home-coverage td:last-child {
  padding-right: 0.625rem;
}

.home-coverage thead th {
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--border-strong);
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.04em;
}

.home-coverage tbody th {
  font-weight: 400;
}

.home-coverage tbody td:first-of-type {
  padding-left: 1.25rem;
}

/* Figures right-aligned against their labels. Qualified by element because
 * `.home-coverage th` alone would otherwise out-specify a bare class and leave
 * the header of a right-aligned column sitting on the left. */
.home-coverage th.home-coverage-num,
.home-coverage td.home-coverage-num {
  text-align: right;
}

/*
 * The move columns centre, they do not right-align.
 *
 * The pill is a lozenge with its own padding, so right-aligning the cell puts
 * the pill's edge under the header while the digits inside sit a further 10px
 * in, and the label reads as offset from its own column. Every pill is one
 * width, so centring the cell centres the label and the figure on the same axis.
 */
.home-coverage th.home-coverage-move,
.home-coverage td.home-coverage-move {
  text-align: center;
}

/* Secondary scale figure: present, but it must not compete with the rates. */
.home-coverage td.home-coverage-soft {
  color: var(--muted);
}

/*
 * The hover band, rounded at both ends.
 *
 * `border-radius` on a `tr` does nothing, so the radius is put on the first and
 * last cell and the background on all of them.
 */
.home-coverage tbody tr td,
.home-coverage tbody tr th {
  transition: background-color 0.12s ease;
}

.home-coverage tbody tr:hover td,
.home-coverage tbody tr:hover th,
.home-coverage tbody tr.is-on td,
.home-coverage tbody tr.is-on th {
  background: var(--paper);
}

.home-coverage tbody tr:hover th:first-child,
.home-coverage tbody tr.is-on th:first-child {
  border-radius: 8px 0 0 8px;
}

.home-coverage tbody tr:hover td:last-child,
.home-coverage tbody tr.is-on td:last-child {
  border-radius: 0 8px 8px 0;
}

.home-coverage a {
  text-decoration: none;
  color: var(--text);
}

.home-coverage tbody tr:hover th a,
.home-coverage tbody tr.is-on th a {
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* The same mark the city wears on the map, so a row and its dot read as one
 * object before anything is hovered. */
.home-coverage-dot {
  display: inline-block;
  width: 0.4375rem;
  height: 0.4375rem;
  margin-right: 0.5rem;
  border-radius: 50%;
  background: var(--accent-dark, #2f6b46);
  vertical-align: 0.08em;
}

.home-coverage tbody tr:hover .home-coverage-dot,
.home-coverage tbody tr.is-on .home-coverage-dot {
  background: var(--text);
}

.home-coverage-note {
  max-width: 58rem;
  margin-top: 0.875rem;
  color: var(--muted);
  font-size: 0.75rem;
  white-space: normal;
}

/*
 * The move, as a market pill.
 *
 * Red for a rise, green for a fall, which is the Japanese convention and the
 * opposite of the American one. The arrow is what actually carries the
 * direction, so a reader who expects green to mean "up" is not misled, and the
 * tint is only there to make the column scannable at a glance.
 *
 * One width for every pill in the column. Sized to content they came out at
 * five different lengths, and a column of right-aligned lozenges with ragged
 * left edges reads as broken alignment even though the digits line up.
 */
.home-pill {
  display: inline-grid;
  grid-template-columns: 0.75rem auto;
  align-items: baseline;
  justify-content: end;
  gap: 0.125rem;
  min-width: 5.25rem;
  padding: 0.25rem 0.625rem;
  border-radius: 999px;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.home-pill-mark {
  font-size: 0.5625rem;
  line-height: 1;
  text-align: left;
}

.home-pill.is-up {
  background: #f8ebe8;
  color: #a44a3a;
}

.home-pill.is-down {
  background: #e9f1ea;
  color: #386b48;
}

.home-pill.is-flat {
  background: var(--paper);
  color: var(--muted-strong);
}

.home-pill-link {
  text-decoration: none;
}

.home-pill-link:hover .home-pill {
  outline: 1px solid currentColor;
}

/*
 * The cities with no monthly report: named, linked and on the map, but not given
 * four empty columns each in the table above.
 */
.home-coverage-rest {
  margin-top: clamp(1.5rem, 3vw, 2rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

.home-coverage-rest h3 {
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.06em;
}

.home-coverage-rest ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4375rem 1.125rem;
  margin: 0.75rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.875rem;
}

.home-coverage-rest a {
  text-decoration: none;
  color: var(--muted-strong);
}

.home-coverage-rest li:hover a,
.home-coverage-rest li.is-on a {
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* ---------- investor: four cards ---------- */

/*
 * Cards, deliberately, and the one place on this page they are right.
 *
 * These four are peers you choose between, not rows you read down: the shape
 * has to say "pick one". The rule this breaks (no cards) is aimed at metrics
 * boxed up to look busy, which is not what these are. The chart that used to sit
 * beside the list is gone; it showed something none of the four modules do.
 */
.home-cards {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1rem, 1.75vw, 1.5rem);
  margin: clamp(2rem, 3.5vw, 3rem) 0 0;
  padding: 0;
  list-style: none;
}

/* Tall cards: the foot is pinned to the bottom so the four figures and the four
 * calls to action sit on two shared lines however long the blurbs run. */
.home-card {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  height: 100%;
  min-height: clamp(15rem, 22vw, 19rem);
  padding: clamp(1.125rem, 1.75vw, 1.5rem);
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #ffffff;
  color: inherit;
  text-decoration: none;
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease,
    transform 0.15s ease;
}

.home-card:hover {
  border-color: var(--border-strong);
  box-shadow: 0 6px 22px rgba(26, 25, 23, 0.07);
  transform: translateY(-2px);
}

.home-card-access {
  color: var(--muted);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
}

.home-card-title {
  font-size: clamp(1rem, 1.25vw, 1.125rem);
  line-height: 1.4;
}

.home-card:hover .home-card-title {
  text-decoration: underline;
  text-underline-offset: 0.25em;
  text-decoration-color: var(--border-strong);
}

.home-card-body {
  color: var(--muted-strong);
  font-size: 0.875rem;
  line-height: 1.7;
}

.home-card-foot {
  display: grid;
  gap: 0.375rem;
  margin-top: auto;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
}

.home-card-figure {
  color: var(--text);
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.home-card-go {
  color: var(--muted);
  font-size: 0.75rem;
}

.home-card:hover .home-card-go {
  color: var(--accent-dark);
}

@media (prefers-reduced-motion: reduce) {
  .home-card {
    transition: none;
  }

  .home-card:hover {
    transform: none;
  }
}

/* ---------- method: the only narrow column ---------- */

.home-method p {
  margin: 1.25rem 0 1.5rem;
  color: var(--muted-strong);
  line-height: 1.95;
}

/* ---------- motion ---------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 0.5s ease-out,
    transform 0.5s ease-out;
}

[data-reveal].is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ---------- narrow screens ---------- */

/*
 * The nation section stacks earlier than everything else.
 *
 * Its table cannot shrink below about 700px, and the map wants 550 at this
 * height, so the two stop fitting side by side well before the 900px breakpoint
 * the rest of the page uses.
 */
@media (max-width: 1180px) {
  .home-nation {
    grid-template-columns: minmax(0, 1fr);
    justify-content: stretch;
  }

  .home-nation-map {
    margin: 0 auto;
  }
}

@media (max-width: 1080px) {
  /* Two by two rather than four in a row: below this a quarter of the width is
   * narrower than the words in the titles. */
  .home-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* The middle slot is the first thing to go: at this width the shot is a
   * postage stamp between two columns that both need the room. */
  .home-answer {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 1.5rem 2rem;
  }

  .home-answer-shot {
    display: none;
  }
}

@media (max-width: 900px) {
  .home-hero {
    grid-template-columns: minmax(0, 1fr);
    min-height: 0;
    gap: 2rem;
  }

  .home-hero-type {
    padding-right: var(--page-gutter);
  }

  .home-hero-view {
    flex-direction: column;
    align-items: stretch;
    justify-self: stretch;
    gap: 1.5rem;
  }

  /*
   * The rail lies back down once the hero stacks: a column of nine names beside
   * a full-width map would spend the width the stack just bought on nothing.
   */
  .home-cities {
    flex-direction: row;
    /* One line that scrolls, not two that wrap: the active marker is a segment
     * of the rule under the row, and a wrapped second row leaves that rule under
     * the wrong names. Hidden scrollbar, but the row clips mid-name at the edge,
     * which is the affordance. */
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    gap: 0 1.125rem;
    padding: 0 var(--page-gutter);
    border-right: 0;
    border-bottom: 1px solid var(--border);
    text-align: left;
  }

  .home-cities::-webkit-scrollbar {
    display: none;
  }

  .home-tab {
    padding: 0 0 0.375rem;
    margin: 0 0 -1px;
    border-right: 0;
    border-bottom: 2px solid transparent;
  }

  .home-tab.is-active {
    border-bottom-color: var(--text);
  }

  /* Stacked, the graphic gets the whole width: the fixed box exists only to
   * leave room for the type beside it and to hold the rail still. */
  .home-hero-map {
    width: auto;
  }

  .home-map-svg {
    max-height: 62svh;
    max-width: 100%;
  }

  .home-map-note {
    padding: 0 var(--page-gutter);
    text-align: left;
  }

  .home-nation,
  .home-invest {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked, the map goes back to being centred above its own table. */
  .home-nation-map {
    margin: 0 auto;
  }

  .home-invest {
    padding-left: var(--page-gutter);
  }

  .home-invest-figure {
    border-left: 1px solid var(--border);
  }
}

@media (max-width: 640px) {
  .home-cards {
    grid-template-columns: minmax(0, 1fr);
  }

  .home-card {
    min-height: 0;
  }

  .home-answer {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.75rem;
  }

  .home-answer-word {
    justify-self: start;
    font-size: 2.5rem;
  }

  .home-figures {
    gap: 1.25rem 2rem;
  }
}
