/* ================================================================
   INTEL — "The family intelligence only Nestify could make."
   Mirrors the Google Pixel Tablet "The tablet only Google could make"
   section: centered headline → subline → play link → 4-col grid.
   No cards, no borders, no tiles. Whitespace does the work.
   ================================================================ */

.intel {
  width: 100%;
  background: var(--page-bg, #f4f2ea);
  /* 🔴 THE TWO VALUES ARE UNEQUAL SO THAT THE SECTION LOOKS EQUAL. They
     were the same clamp on both sides, which is the obvious thing to
     write and the wrong thing to see. Measured at 1440x900, from the
     section's edges to the actual INK — not to the element boxes, which
     is where the mistake hides:

                      box-to-box    ink-to-ink
       top               97.3          93.3
       bottom            81.3          63.2

     Same declared 81.3 both ends, 30px apart to the eye. The two ends
     are not the same kind of edge: the top runs into a 48px headline
     whose box starts 16px below the padding and whose cap sits inside
     its own line box, the bottom runs out of a 17px paragraph whose last
     line leaves its leading below the final descender. Neither of those
     is a number anyone typed; both are what line boxes do.

     ±15px splits the 30 evenly and lands both ends near 78px. It is a
     COMPENSATION, not a spacing value — if the headline's size or either
     line-height changes, re-measure ink-to-ink rather than nudging this.

     🔴 NEITHER END IS THIS SECTION'S EDGE, and that is what the numbers
     above keep getting wrong. This block moved: it used to sit under the
     deck and now sits directly under the hero, with a block of cards below
     it as before. Both neighbours end in something other than a box edge,
     so both gaps have to be measured from the INK or from the visible
     edge, never from `padding`:

       ABOVE  .dv__hero is a 100svh sticky stage and its last ink is
              .dv__hero-fine, which stops 78px short of the section's
              bottom. So the eye's gap is 78 + this padding, not this
              padding.
       BELOW  the cards bring no padding-top and the first one is a hard
              pale edge, so that end IS a real edge — but the body's last
              line stops ~7px above its own box on the descender.

     ⚠️ THAT LOWER NEIGHBOUR HAS CHANGED IDENTITY ONCE ALREADY. It was
     .ph-blocks when these numbers were taken and it is .ffit--flush now;
     both open on a card edge with no top padding, so the measurement held
     through the swap. It is named generically above for that reason — what
     the arithmetic depends on is the EDGE, not which section supplies it.

     Measured at 1440x900 after the move, with 66 / 181.5 declared:

                        declared   what the eye gets
       hero -> headline    66.0          ~163
       body -> card       181.5          ~188

     🔴 THE FOOT CAME IN, ON REQUEST, AND THE HEAD CAME WITH IT so the
     two ends stay level — closing one alone would have re-opened the
     imbalance this section was tuned out of one edit ago. Scanned off the
     rendered pixels at 43 / 128 declared:

       hero ink   210  ->  headline ascender  337     127
       body ink   543  ->  card edge          679     136

     🔴 The ±2 is the same kind of lie as the ±15 above, just smaller now
     that the two ends are closer together. They are different KINDS of
     edge — a descender against a hard card edge below, an ascender
     against the hero's small print above — so the boxes are set unequal
     for the ink to read equal. It was ±6 for the PREVIOUS pair of
     neighbours; a compensation does not survive a reorder, re-scan it.

     (There is also an unexplained 16px between .intel__inner's content
     top and .intel__head's box. It is inside the 30 being corrected
     here, so the fix holds either way, but it is worth finding before
     anyone tunes this again.) */
  padding-top: calc(clamp(1.5rem, 5vh, 3rem) - 2px);
  padding-bottom: calc(clamp(5rem, 14vh, 9rem) + 2px);
}

.intel__inner {
  max-width: 77.5rem;
  margin-inline: auto;
  padding-inline: max(5vw, 32px);
}

/* ── Centered head block ── */
.intel__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin-bottom: 4rem;
}

.intel__headline {
  font-family: var(--font--primary, "Google Sans", sans-serif);
  /* 🔴 THE CEILING IS THE LINE, NOT TASTE. This headline is `white-space:
     nowrap` (see below), so the only question is how large it goes before
     it stops fitting on one. Measured at 1440 against its 1096px
     container, at weight 600:

       2.75rem   936px    160px spare
       3rem     1022px     74px spare   <- this
       3.25rem  1107px     overflows

     3rem is the last step that fits, and 74px of that is not margin to
     spend — bolder type is wider, and the sentence is a fixed string, so
     anything that changes either eats straight into it.

     🔴 THE vw TERM IS 3.4, RE-DERIVED. It was 2.4vw, which resolved to
     34.5px and let the 2.25rem cap bind at 1440 — the clamp was doing
     nothing above about 1350px wide. 3.4vw hits 48px at 1412, so the cap
     takes over just below the width the line was measured at, and below
     that the type shrinks with the window instead of overflowing it. */
  font-size: clamp(1.5rem, 3.4vw, 3rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--nes-ink, #1a1a1a);
  margin: 0 0 1rem;
  white-space: nowrap;
}

/* 🔴 WEIGHT ONLY — THE COLOUR CAME OUT AGAIN. These two runs were briefly
   --nes-blue-2 as well, and the sentence is back to one ink. Worth saying
   why the blue was defensible so nobody re-derives it: --nes-blue-2 is the
   one of styles.css's four blues its own comment labels "brand blue
   (headline)", and as ink on the page's #f3f6f6 it measures 3.39:1 —
   under AA's 4.5 for body copy, over the 3:1 that large type gets, which
   this line clears at 48px/700. It was legible; it just made the headline
   read as two colours of claim.

   🔴 700 EATS INTO THE ONE THING THIS HEADLINE HAS NO SLACK IN, and that
   is still true with the colour gone. The line is `white-space: nowrap`
   and the note above records 74px of spare at 1440 with the whole line at
   600. Bolding 26 of its 48 characters spends part of that: measured, it
   runs 1033px against the same 1096px container, so 63px is left. Anything
   that makes the sentence longer, the weight heavier or the container
   narrower has to be measured against THAT number, not against the 74. */
.intel__hl {
  font-weight: 700;
}

.intel__subline {
  font-family: var(--font--body, "Google Sans", sans-serif);
  font-size: clamp(1rem, 1.4vw, 1.25rem);
  font-weight: 400;
  color: var(--nes-muted, #787165);
  margin: 0 0 1.5rem;
  line-height: 1.5;
}

/* ── Play link ── */
.intel__link {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--font--ui, "Google Sans", sans-serif);
  font-size: 1.125rem;
  font-weight: 500;
  color: var(--nes-blue-2, #1e88e5);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease;
}
.intel__link:hover {
  border-bottom-color: var(--nes-blue-2, #1e88e5);
}

.intel__play {
  width: 1.25rem;
  height: 1.25rem;
  flex-shrink: 0;
}

/* ── 4-column grid ── */
.intel__cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2.5rem;
}

/* ── Single column ── */
.intel__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

/* 🔴 THE ICON AND THE LABEL ARE ONE LINE, and that is what the sizes
   below are answering to. Stacked, the icon was a 40px object with the
   column's whole width to itself; beside 18px type it is a bullet, and a
   40px bullet next to an 18px word reads as two things that happen to be
   near each other. 24px puts it inside the label's own line box (18px at
   1.3 = 23.4px), so the pair reads as one line with a mark at the front. */
.intel__top {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 0.6rem;
}

.intel__icon {
  width: 1.75rem;  /* 28px — the label's line box, near enough */
  height: 1.75rem;
  color: var(--nes-ink, #1a1a1a);
  flex-shrink: 0;
}

/* 🔴 22px AGAINST THE BODY'S 17, because 18 against 17 is not a
   distinction, it is a rounding error. The two were a single pixel apart
   and doing the same job at the same weight-ish, so the pair read as one
   block of text with a full stop in the middle of it. 1.29x is a real
   step on a type scale, and with 500 against 400 on top of it the label
   is plainly the heading and the sentence is plainly the sentence.

   🔴 THE BODY DID NOT MOVE, on purpose. Shrinking it would have widened
   the gap just as well and cost more: max-width is in `ch`, so a smaller
   body font means a narrower box AND more characters per line at once,
   and the two-line fit that the whole row of columns depends on would
   have had to be re-measured from scratch. Raising the label changes one
   line box and nothing else. */
/* 🔴 700 AGAINST THE BODY'S 500, because the size step was carrying the
   whole hierarchy alone. The note above chose 22px over 17px on the
   argument that 1.29x is a real step on a type scale — true, but both ran
   at 500 after the body was raised, so the only thing separating the
   heading from the sentence was 5px of size. Weight is the cheaper
   signal and it does not touch the line-fit arithmetic below.

   This line is `white-space: nowrap` in a 244px grid column, so the
   weight is a fit question too: "It remembers." is the longest of the
   four and measures 148px at 700 — and it does not sit alone, it sits
   after a 28px icon and a 0.55rem gap, so the row is 185px of the 244.
   Still clear, but that is the number to check, not the 148. */
.intel__label {
  font-family: var(--font--ui, "Google Sans", sans-serif);
  font-size: 1.375rem;
  font-weight: 700;
  color: var(--nes-ink, #1a1a1a);
  margin: 0;          /* the row below it owns the gap now */
  line-height: 1.3;
  white-space: nowrap;
}

.intel__body {
  font-family: var(--font--body, "Google Sans", sans-serif);
  font-size: 1.0625rem;
  /* 🔴 500, up from 400. It carries the whole statement — the label is a
     heading, this is the thing being said — and at 17px on a near-white
     ground 400 was thin enough to read as a caption. */
  font-weight: 500;
  /* 🔴 INK, not --nes-muted. The body carried the whole statement for a
     while and grey was too quiet for it; the label is back now and the
     hierarchy is carried by SIZE AND WEIGHT instead — 1.125rem/500 over
     1.0625rem/400 — which is enough separation without dropping the
     sentence into a second colour. */
  color: var(--nes-ink, #1a1a1a);
  /* 🔴 1.35, down from 1.55. 1.55 is a paragraph's leading and this is
     two lines — at that spacing the pair floats apart and stops reading
     as one sentence that happened to wrap. Tighter also buys back 7px of
     column height, which the label took when it went to 22px. */
  line-height: 1.35;
  margin: 0;
  /* 🔴 21ch, DOWN FROM 26, AND 20 IS THE FLOOR. Swept against the four
     sentences at 1440 and read off the rendered line count:

       26ch  244px  2 2 2 2      the cap never bit — the column is 244px
       21ch  230px  2 2 2 2      one step of margin
       20ch  219px  2 2 2 2      the last width that holds
       19ch  208px  2 2 3 2      "Remembers the allergies…" goes over

     Above 22ch the value did nothing at all: the grid column is 244px, so
     anything wider than that was a cap on a box that was already narrower.
     21 is the first number that is actually doing something, with one
     step in hand before the longest of the four wraps to three lines and
     the row of columns stops sitting level. */
  max-width: 21ch;
}

/* ── Scroll-reveal ── */
@media (prefers-reduced-motion: no-preference) {
  .intel.is-animated .intel__head {
    opacity: 0;
    transform: translateY(1rem);
    transition: opacity 0.5s ease, transform 0.5s ease;
  }
  .intel.is-animated .intel__head.is-visible {
    opacity: 1;
    transform: none;
  }
  .intel.is-animated .intel__col {
    opacity: 0;
    transform: translateY(1.25rem);
    transition: opacity 0.4s ease, transform 0.4s ease;
  }
  .intel.is-animated .intel__col.is-visible {
    opacity: 1;
    transform: none;
  }
  .intel__col:nth-child(1) { transition-delay: 0ms; }
  .intel__col:nth-child(2) { transition-delay: 60ms; }
  .intel__col:nth-child(3) { transition-delay: 120ms; }
  .intel__col:nth-child(4) { transition-delay: 180ms; }
}

/* ── Tablet: 2×2 ── */
@media (max-width: 1023px) {
  .intel__cols {
    grid-template-columns: repeat(2, 1fr);
    gap: 3rem 2rem;
  }
}

/* ── Mobile: single column ── */
@media (max-width: 639px) {
  .intel__cols {
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }
  .intel__col {
    align-items: flex-start;
    text-align: left;
  }
  .intel__head {
    align-items: flex-start;
    text-align: left;
  }
  .intel__headline {
    white-space: normal;   /* allow wrap on small screens */
  }
}


/* ================================================================
   PH-BANNER — full-width strip placeholder before the intel section
   ================================================================ */

/* 🔴 THE FOOT IS ZERO, and it is not a tidy-up. The stage inside this
   band is a screen tall with the pile centred in it, so the band already
   ENDS with ~104px of empty stage under the last card's edge — 48px of
   flex slack below the pile plus the pile's own overhang guard. 2rem on
   top of that was 32px of padding separating two things that were already
   104px apart.

   🔴 THE REASON SURVIVES EVERY REORDER, THE NEIGHBOURS DO NOT. The 104px
   is a property of the STAGE — a screen tall with the pile centred in it —
   not of whatever happens to sit under it, so the zero has outlived three
   different arrangements. The names in this note have not, and both had
   gone stale before this correction:

     when written   .intel followed the band; the pair read two to one
     then           the deck moved below .intel, opening onto .dv__cmp
     now            .dv__cmp is deleted, so the foot opens onto .dv__priv,
                    and .ph-blocks above has been replaced by .ffit--flush

   Order today: hero, .intel, .ffit--flush, this band, .dv__priv, .dv__specs.

   ⚠️ AND NONE OF IT IS RENDERING. The band is currently wrapped in a
   template tag in device.html (search "THE DECK IS HIDDEN"), so these two
   values are dormant. They become live again the moment the deck is
   restored — see restore-deck.sh — which is why they are tuned and not
   deleted.

   The head keeps its 2rem: what is above the band is .ffit--flush, which
   ends on a hard card edge and not on a screen of slack. */
.ph-banner {
  width: 100%;
  background: var(--page-bg, #f4f2ea);
  padding-top: 2rem;
  padding-bottom: 0;
}

.ph-banner__inner {
  max-width: 77.5rem;
  margin-inline: auto;
  padding-inline: max(5vw, 32px);
}

.ph-banner__bar {
  width: 100%;
  height: 5rem;
  border-radius: 1.25rem;
  background: #E4E9ED;
}

@media (max-width: 639px) {
  .ph-banner__bar { height: 4rem; }
}


/* ================================================================
   PH-BLOCKS — placeholder color blocks
   Top row  : left wider  3fr : right narrower 2fr   (tall ~320px)
   Bottom row: left narrower 2fr : right wider 3fr   (short ~260px)
   Colors sampled from the reference screenshot.
   ================================================================ */

.ph-blocks {
  width: 100%;
  background: var(--page-bg, #f4f2ea);
  padding-bottom: clamp(3rem, 6vh, 5rem);
}

.ph-blocks__inner {
  max-width: 77.5rem;
  margin-inline: auto;
  padding-inline: max(5vw, 32px);
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* ── Top row: equal columns 1:1 ── */
.ph-blocks__row--tall {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}

/* ── Bottom row: left narrower 2fr : right wider 3fr ── */
.ph-blocks__row--short {
  display: grid;
  grid-template-columns: 2fr 3fr;
  gap: 1.25rem;
}

.ph-blocks__card {
  border-radius: 1.5rem;
  overflow: hidden;
}

/* Heights */
.ph-blocks__row--tall  .ph-blocks__card { min-height: 20rem; }
.ph-blocks__row--short .ph-blocks__card { min-height: 20rem; }

/* Colors from reference */
.ph-blocks__card--a { background: #E4E9ED; }   /* top-left */
.ph-blocks__card--b { background: #E4E9ED; }   /* top-right */
.ph-blocks__card--c { background: #DBE0DF; }   /* bottom-left */
.ph-blocks__card--d { background: #DBE0DF; }   /* bottom-right */

@media (max-width: 639px) {
  .ph-blocks__row--tall,
  .ph-blocks__row--short {
    grid-template-columns: 1fr;
  }
  .ph-blocks__row--tall  .ph-blocks__card { min-height: 14rem; }
  .ph-blocks__row--short .ph-blocks__card { min-height: 14rem; }
}
