/* The Interesting People wall.

   Everything here uses the tokens in css/folio.css - no new colour,
   no new font. The hover is the site's one hover, borrowed from .folio in
   css/tiles.css: 3px lift, gold border, .25s. This is a new grid, not a
   second gesture. */

/* The mono face is declared here rather than borrowed from prompt-creator.css,
   which this page does not load. Same stack, so the two pages match. */
:root{ --ip-mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }

/* ---------- the controls ---------- */
/* Each control is a labelled field, not a bare box. With one search and three
   filters, a row of unlabelled selects makes the reader open each to find out
   what it does. The labels are the eyebrow type already used on this page, so
   this is the site's existing voice at a smaller size.

   The labels are real <label for=...>, and the controls no longer carry an
   aria-label: an aria-label OVERRIDES the visible text for a screen reader,
   so keeping both would have read out something different from what is on
   screen. */
.ip-bar{
  display:flex; flex-wrap:wrap; gap:14px; align-items:end;
  margin:0 0 22px; padding-bottom:18px; border-bottom:1px solid var(--hairline);
}
.ip-field{ display:flex; flex-direction:column; gap:9px; min-width:0; }
.ip-field--grow{ flex:1 1 240px; }
/* A gold bar with dark type, square-cornered, sitting exactly over its own
   control. Sentence case, not capitals: four shouted labels in a row read as
   a warning, and this is a set of ordinary controls.

   align-self:stretch is what squares the label off against the box beneath —
   the field is a column, so the label takes the column's width, which is the
   control's width. Left and right edges line up by construction rather than
   by a number that would need keeping in step. */
.ip-field > label{
  align-self:stretch;
  background:var(--gold); color:#17130a;
  font-family:var(--text); font-size:12.5px; font-weight:500; line-height:1;
  padding:8px 14px; border-radius:0; border:1px solid var(--gold);
  box-sizing:border-box; white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis;
}
/* One rule for all four, so a fifth cannot drift away from the other four.
   The height is explicit because an <input type=search> and a <select> do NOT
   compute the same height from the same padding — 42px against 44px — and
   with the row aligned on its baseline that put "Find a Channel" two pixels
   out of line with the other three. */
.ip-search, .ip-cat, .ip-fav, .ip-sub,
.ip-med, .ip-subj, .ip-nat, .ip-live{
  box-sizing:border-box; height:44px;
  background:var(--surface); border:1px solid var(--hairline); border-radius:8px;
  color:var(--paper); font-family:var(--text); font-size:15px; padding:0 14px;
  min-width:0;
}
.ip-search{ width:100%; }
.ip-search::placeholder{ color:var(--gold-dim); }
.ip-search:focus, .ip-cat:focus, .ip-fav:focus, .ip-sub:focus,
.ip-med:focus, .ip-subj:focus, .ip-nat:focus, .ip-live:focus{
  outline:2px solid var(--gold); outline-offset:2px; border-color:var(--gold);
}
/* The live count. It is the only number on the page that answers "what did
   that filter just do", and it was 13px grey — quieter than everything it was
   reporting on. The figure is now the size of a figure; the words beside it
   stay small, because "creators" is not the news. */
.ip-count{
  margin-left:auto; display:flex; align-items:baseline; gap:8px;
  padding-bottom:6px;
}
.ip-count b{
  font-family:var(--display); font-size:30px; font-weight:600; line-height:1;
  letter-spacing:-.02em; color:var(--gold);
  font-variant-numeric:tabular-nums;
}
.ip-count span{ font-size:13px; color:var(--muted); }
/* A number that changes without moving is easy to miss. */
@keyframes ip-count-bump{
  0%{ transform:translateY(0) }
  35%{ transform:translateY(-3px) }
  100%{ transform:translateY(0) }
}
.ip-count.is-changed b{ animation:ip-count-bump .34s ease; }
@media (prefers-reduced-motion:reduce){
  .ip-count.is-changed b{ animation:none; }
}

/* ---------- the wall ---------- */
.ip-grid{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(116px,1fr)); gap:10px;
}
.ip-person{
  position:relative; aspect-ratio:1/1; border-radius:6px; overflow:hidden;
  border:1px solid var(--hairline); background:var(--surface);
  padding:0; cursor:pointer; isolation:isolate; display:block; width:100%;
  transition:transform .25s ease, border-color .25s ease;
}
.ip-person:hover{ transform:translateY(-3px); border-color:var(--gold); }
/* The browser hides [hidden] elements with `display:none` from its own
   stylesheet, and a class selector beats that. So `.ip-person{display:block}`
   above quietly cancelled it: the search set `hidden` on 853 tiles, the count
   said "20 of 873", and all 873 stayed on screen. The filter had never once
   worked, and the tests missed it because they read the `hidden` property
   rather than what rendered. */
.ip-person[hidden]{ display:none; }
.ip-person:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }
.ip-person img{
  width:100%; height:100%; object-fit:cover; display:block;
  filter:grayscale(1) contrast(1.04);
  transition:filter .25s ease;
}
.ip-person:hover img, .ip-person:focus-visible img{ filter:grayscale(0); }

/* The name, held back until the face is asked about. Same scrim geometry as
   the folio tiles - 82% black from 25% down - so it clears 4.5:1 over a light
   photograph as well as a dark one. */
.ip-name{
  position:absolute; inset:0; z-index:1; display:flex; align-items:flex-end;
  padding:8px; font-size:11px; line-height:1.25; color:#fff; text-align:left;
  background:linear-gradient(180deg,rgba(0,0,0,0) 25%,rgba(0,0,0,.82) 100%);
  opacity:0; transition:opacity .25s ease;
}
.ip-person:hover .ip-name, .ip-person:focus-visible .ip-name{ opacity:1; }

/* Anyone with no usable portrait stands as type on the dark ground. They are
   not failures to be papered over with a silhouette - the register says what
   it has. Nobody is in this state today: the 92 who once were now carry either
   a free photograph or one the Duke made. The rule stays because the next
   batch may arrive before its pictures do.

   Counts are deliberately not written into these comments any more. This file
   said "872 faces" while the wall held 1,040. */
.ip-person.ip-noimg{ background:linear-gradient(145deg,#1a1a1d,#26262b); }
.ip-person.ip-noimg .ip-name{
  opacity:1; background:none; align-items:center; justify-content:center;
  text-align:center; font-family:var(--display); font-size:12px;
  color:var(--secondary); padding:10px;
}
.ip-person.ip-noimg:hover .ip-name{ color:var(--paper); }

.ip-empty{ color:var(--muted); font-size:15px; padding:30px 0; }

/* ---------- the Content Creators wall ---------- */
/* The same wall, one deliberate difference. The People tiles are greyscale at
   rest because 1,040 photographs of wildly different age and stock only read
   as one surface once the colour is off them. A channel's picture IS its
   colour - CNET red, BBC Earth green, a hundred brand marks - and Ashley chose
   on 13 Sep 2026 to keep it. So this page cancels the filter rather than
   forking the tile. */
.cr-wall .ip-person img{ filter:none; }
.cr-wall .ip-person:hover img{ filter:brightness(1.08); }
/* Marks are often drawn to the edge of the square, so they sit flush where a
   cropped photograph does not. A hair of inset keeps them off the border. */
.cr-wall .ip-person{ background:#17171a; }

/* The figures line, where a person's tagline sits on the other wall. */
.cr-figures{
  font-size:15px; line-height:1.6; color:var(--secondary); margin:14px 0 0;
  font-variant-numeric:tabular-nums;
}

/* ---------- the panel ---------- */
.ip-panel{
  position:fixed; inset:0; z-index:200; display:none;
  background:rgba(0,0,0,.86); padding:24px;
  align-items:center; justify-content:center;
}
.ip-panel[aria-hidden="false"]{ display:flex; }
.ip-card{
  /* The close button anchors to this, not to the panel - without it the x
     positions against the fixed backdrop and floats off in the corner. */
  position:relative;
  background:var(--canvas); border:1px solid var(--hairline); border-radius:12px;
  max-width:620px; width:100%; max-height:88vh; overflow:auto;
  display:grid; grid-template-columns:220px 1fr;
}
.ip-card img{ width:100%; height:100%; object-fit:cover; display:block; background:var(--surface); }
.ip-card .ip-body{ padding:26px 62px 22px 26px; }
.ip-card h2{
  font-family:var(--display); font-size:24px; font-weight:600;
  letter-spacing:-.01em; color:var(--paper); margin:0;
}
.ip-dates{ font-size:14px; color:var(--muted); margin:4px 0 0; }
.ip-cat-tag{
  display:inline-block; margin:12px 0 0; padding:4px 10px; border-radius:999px;
  font-size:12px; color:var(--gold); background:var(--gold-soft);
  border:1px solid var(--gold-line);
}
.ip-tagline{ font-size:15px; line-height:1.6; color:var(--secondary); margin:14px 0 0; }
.ip-links{ margin:18px 0 0; }
.ip-links a{ font-size:14px; color:var(--gold); text-decoration:none; border-bottom:1px solid var(--gold-line); }
.ip-links a:hover{ color:var(--gold-hi); }
/* Required, not decorative: these photographs are other people's work, and
   CC BY obliges us to name them wherever the picture appears. */
.ip-credit{
  margin:18px 0 0; padding-top:14px; border-top:1px solid var(--hairline);
  font-size:12px; line-height:1.5; color:var(--muted);
}
.ip-close{
  position:absolute; top:14px; right:14px; width:36px; height:36px;
  background:none; border:1px solid var(--hairline); border-radius:50%;
  color:var(--paper); font-size:22px; line-height:1; cursor:pointer;
}
.ip-close:hover{ border-color:var(--gold); color:var(--gold); }
.ip-close:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; }

@media (max-width:640px){
  .ip-grid{ grid-template-columns:repeat(auto-fill,minmax(92px,1fr)); gap:8px; }
  .ip-card{ grid-template-columns:1fr; }
  .ip-card img{ aspect-ratio:1/1; height:auto; }
  .ip-count{ margin-left:0; width:100%; }
}
@media (prefers-reduced-motion:reduce){
  .ip-person, .ip-person img, .ip-name{ transition:none; }
  .ip-person:hover{ transform:none; }
}

.ip-intro{ font-size:16px; line-height:1.65; color:var(--secondary); max-width:62ch; margin:0 0 26px; }
.ip-credit-note{ font-size:12px; line-height:1.6; color:var(--muted); max-width:70ch; margin:26px 0 0; }

/* ---------- imagined portraits ----------

   Some people in the register have no photograph anyone is free to publish.
   Where the Duke supplies an invented one it must not pass as a photograph:
   the wall is real pictures with a named photographer under each, and one
   convincing fake devalues all of them. Twenty-nine of the gaps are living
   people, who are in a position to mind.

   At rest an imagined portrait is grey like everything else - the wall reads
   as one library rather than a set with patches in it. The difference shows
   when you ask about a face: a photograph warms to its own colour, an
   imagined portrait turns gold. It has no true colour to return to.

   Hover does not exist on a phone, so the tile is not the only disclosure.
   The line under the grid says it in words, and the panel says it plainly
   where a photographer's name would otherwise go. */
.ip-person.ip-imagined:hover img,
.ip-person.ip-imagined:focus-visible img{
  filter:grayscale(1) sepia(1) hue-rotate(-12deg) saturate(2.1) brightness(1.02);
}
.ip-person.ip-imagined:hover{ border-color:var(--gold-line); }
.ip-credit.ip-credit-imagined{ color:var(--gold-dim); }

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

   Built to the pattern the Artist Prompt Creator established: back button,
   the name set large over three lines, a lede, a gold italic line, a button,
   and a cutout portrait facing the text. Same tokens, same rhythm - this is
   the second instance of one pattern, not a second pattern.

   The counts are not written here. make-people-data.py fills .ip-total and
   .ip-cats from the same pass that writes the tiles, because the old intro
   still said "eight hundred and seventy-two" when the wall held 1,040. A
   number typed into a page is a number that goes stale. */
.ip-hero-zone{ padding-bottom:clamp(30px,4vw,52px); }

.ip-back{
  display:inline-block; margin-bottom:clamp(28px,4vw,46px);
  font-family:var(--ip-mono); font-size:11px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--gold); text-decoration:none;
  border:1px solid var(--gold-line); padding:11px 20px;
}
.ip-back:hover{ border-color:var(--gold); background:var(--gold-soft); }
.ip-back:focus-visible{ outline:2px solid var(--gold); outline-offset:3px; }

.ip-hero{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.86fr);
  gap:clamp(26px,4vw,58px); align-items:center;
}
.ip-hero-title{
  margin:0; font-family:var(--display); font-weight:600; color:var(--paper);
  font-size:clamp(42px,6.2vw,76px); line-height:.98; letter-spacing:-.022em;
}
.ip-hero-lede{
  margin:clamp(20px,2.8vw,32px) 0 0; font-family:var(--display);
  font-size:clamp(17px,1.6vw,19px); line-height:1.55;
  color:var(--secondary); max-width:36ch; text-wrap:pretty;
}
.ip-hero-pull{
  margin:clamp(18px,2.4vw,28px) 0 0; font-family:var(--display); font-style:italic;
  font-size:clamp(18px,1.8vw,21px); color:var(--gold);
}
.ip-hero-cta{
  display:inline-block; margin-top:clamp(22px,3vw,34px);
  background:var(--gold); color:#17130a; text-decoration:none;
  font-family:var(--text); font-size:15px; font-weight:500;
  padding:13px 26px; border-radius:999px; border:1px solid var(--gold);
}
.ip-hero-cta:hover{ background:var(--gold-hi); border-color:var(--gold-hi); }
.ip-hero-cta:focus-visible{ outline:2px solid var(--gold); outline-offset:3px; }

.ip-hero-figure{ margin:0; }
.ip-hero-figure img{ display:block; width:100%; height:auto; }

.ip-rule-eyebrow{
  display:flex; align-items:center; gap:14px; margin:0 0 clamp(20px,3vw,30px);
}
.ip-rule-eyebrow::before{
  content:""; width:64px; height:1px; background:var(--gold-line); flex:none;
}
.ip-rule-eyebrow span{
  font-family:var(--ip-mono); font-size:10px; font-weight:500;
  letter-spacing:.24em; text-transform:uppercase; color:var(--gold);
}

.ip-why{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.7fr);
  gap:clamp(28px,5vw,68px); align-items:start;
}
.ip-why-text p{
  margin:0 0 1.1em; font-family:var(--display);
  font-size:17px; line-height:1.66; color:var(--secondary);
}
.ip-why-text p:first-child{ font-size:19px; line-height:1.55; color:var(--paper); }
.ip-why-text p:last-child{ margin-bottom:0; }

.ip-stats{ display:flex; flex-direction:column; }
.ip-stat{ padding:20px 0; border-top:1px solid var(--hairline); }
.ip-stat:first-child{ border-top:0; padding-top:0; }
.ip-stat b{
  display:block; font-family:var(--display); font-weight:400;
  font-size:clamp(27px,3.2vw,37px); line-height:1; color:var(--gold);
  font-variant-numeric:tabular-nums;
}
.ip-stat span{
  display:block; margin-top:9px; font-family:var(--ip-mono); font-size:10px;
  letter-spacing:.2em; text-transform:uppercase; color:var(--muted);
}

@media (max-width:780px){
  .ip-hero{ grid-template-columns:1fr; }
  /* The portrait leads on a phone, as it does on the Prompt Creator. */
  .ip-hero-figure{ order:-1; max-width:340px; }
  .ip-why{ grid-template-columns:1fr; }
}

/* ---------- the Famous Artists wall ---------- */

/* Third wall on this stylesheet, and it needed two new rules. Everything else
   - the bar, the grid, the tiles, the panel, the hero, the statistics band -
   is the People wall's, unchanged. */

/* The hero carries no cut-out portrait. Every face in this database is one the
   Duke imagined, so promoting one of them to the top of the page would give a
   single invented likeness of a named artist the status of a masthead. Text
   alone until there is an image that is nobody in particular. */
.ip-hero--solo{ grid-template-columns:minmax(0,1fr); }
.ip-hero--solo .ip-hero-lede{ max-width:52ch; }

/* The line under the description: subjects, and the years the artist worked.
   Quieter than the description above it and above the link below it, which is
   the order the eye should take them in. */
.fa-meta{
  margin:12px 0 0; font-size:13px; line-height:1.55; color:var(--muted);
}

/* Four filters is one more than any other wall here, and on a phone they came
   out stacked six rows deep - 536px of controls above an 812px screen, so the
   first face sat below the fold on a page whose whole point is the faces.
   Two-up below 560px: the search keeps the full width it needs, the four
   selects pair off, and the bar comes down to three rows.

   Scoped to this wall. The People and Creators bars hold fewer controls, fit
   already, and are not this change's business. */
@media (max-width:560px){
  .fa-wall .ip-field{ flex:1 1 calc(50% - 7px); }
  .fa-wall .ip-field--grow{ flex:1 1 100%; }
}
