/*
Theme Name:  Dr. P. S. Vohra
Description: Editorial theme for Dr. P. S. Vohra's archive of newspaper columns,
             broadcast appearances and school work. Ported from the static build
             in site/index.html.
Version:     1.9.4
Requires PHP: 8.0
Text Domain: drpsvohra
*/

/* The ported stylesheet lives in assets/css/base.css and is enqueued from
   functions.php. This file carries the theme header and WordPress-specific
   overrides only. */

/* ---- WordPress core classes the static build never needed ---- */
.screen-reader-text{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0
}
.alignleft{float:left;margin:0 1.2rem 1rem 0}
.alignright{float:right;margin:0 0 1rem 1.2rem}
.aligncenter{margin-left:auto;margin-right:auto;display:block}
.wp-caption{max-width:100%}
.wp-caption-text{font-size:.82rem;color:var(--ink-3);margin-top:.4rem}

/* ================================================================
   Archive and single-article — screens the static build never had.
   Everything else is inherited from assets/css/base.css.
   ================================================================ */

.wrap-narrow{max-width:760px}

/* ================================================================
   Page header — the block every inner page opens with.

   `.sechead` is the *in-page* section head on the homepage: an eyebrow and
   an h2 over a column of content, with its dek capped at 48ch to suit that
   column. Borrowing it for page-level h1s meant every listing page carried
   a column measure across the full 1560px wrap, plus a `.sechead h1` patch
   to undo the h2 sizing. `.pagehead` is the page-level counterpart, and the
   only head an inner page uses: one type scale, one dek measure, one gap to
   the content below, and an optional right-hand slot for a control such as
   the writings filter.
   ================================================================ */

/* Every listing grid hangs its top margin off this, so the distance from
   header to first row is the same number on /articles/, /books/, /videos/
   and /stba/ rather than three values that happened to be typed. */
:root{--page-gap:clamp(30px,3vw,46px)}

.pagehead{
  display:flex;align-items:flex-end;justify-content:space-between;
  gap:28px;flex-wrap:wrap
}
.pagehead-text{flex:1 1 460px;min-width:0}

/* base.css sizes `.sechead h2`; this is the same scale one step up, and it
   is set here rather than on a bare h1 so a page can still use an h1
   somewhere else without inheriting a page header's proportions. */
.pagehead-title{
  font-family:Fraunces,Georgia,serif;font-weight:900;
  font-size:clamp(26px,3.6vw,40px);line-height:1.12;
  letter-spacing:-.015em;margin:12px 0 0
}
body.lang-hi .pagehead-title,
.pagehead-title:lang(hi){
  font-family:"Tiro Devanagari Hindi",Georgia,serif;
  font-weight:400;line-height:1.32;letter-spacing:0
}
/* Mirrors `.art-title:lang(pa)` — Fraunces has no Gurmukhi, so a page whose
   title is Punjabi would otherwise fall through to a system default. */
.pagehead-title:lang(pa){
  font-family:"Noto Sans Gurmukhi",system-ui,sans-serif;
  font-weight:700;line-height:1.35;letter-spacing:0
}

/* Not capped at `.sechead p`'s 48ch: a page's standing description runs the
   width of the header row, not the width of a card column. */
.pagehead-dek{
  margin:11px 0 0;max-width:62ch;
  color:var(--ink-2);font-size:15.5px;line-height:1.65
}

.pagehead-aside{flex:none}

/* Listing grids hang their own `--page-gap` off the header, but prose does
   not carry a top margin, so a plain page needs the gap set here. */
.pagehead + .art-body{margin-top:var(--page-gap)}

/* /stba/ shows the same tiles as the homepage panel, but that panel is half
   of a split and sizes its grid for a narrow column. Across a full page two
   columns would set each tile about 700px wide. */
.stba-archive .sgrid{grid-template-columns:repeat(4,1fr);gap:20px;margin-top:var(--page-gap)}
@media (max-width:1040px){ .stba-archive .sgrid{grid-template-columns:repeat(2,1fr);gap:14px} }
@media (max-width:560px){ .stba-archive .sgrid{grid-template-columns:1fr} }

/* The About page opens with the same `.pagehead` row as every other inner
   page; the portrait and the biography are the split below it. `.about p`
   carries no top margin of its own, so the distance from header to split is
   set here — the same `--page-gap` the listing grids hang off. */
.pagehead + .about{margin-top:var(--page-gap)}

/* The control drops under the text before the text starts wrapping badly,
   and left-aligns with it rather than hanging off the right edge alone. */
@media (max-width:760px){
  .pagehead{align-items:flex-start}
  .pagehead-aside{margin-top:4px}
}

.filter-btn{
  display:inline-flex;align-items:center;gap:9px;
  padding:10px 18px;border-radius:999px;cursor:pointer;
  background:var(--surface);color:var(--ink);
  border:1px solid var(--line);
  font:600 13.5px/1 Inter,system-ui,sans-serif;
  transition:border-color .18s,background .18s,transform .18s
}
.filter-btn:hover{border-color:var(--line-2);transform:translateY(-1px)}
.filter-btn svg{width:17px;height:17px;flex:none}
.filter-badge{
  min-width:19px;height:19px;padding:0 5px;border-radius:999px;
  display:inline-grid;place-items:center;
  background:var(--lilac);color:var(--surface);
  font-size:11px;font-variant-numeric:tabular-nums
}

/* Active facets, echoed outside the dialog — with the panel closed there is
   otherwise nothing on the page saying what is filtered. */
.active-filters{
  display:flex;flex-wrap:wrap;gap:8px;align-items:center;
  margin:22px 0 4px
}
.active-filters .chip{
  display:inline-flex;align-items:center;gap:7px;
  text-decoration:none;border:1px solid transparent;
  background:var(--t-lilac);color:var(--lilac)
}
.active-filters .chip-x{font-size:14px;line-height:1;opacity:.7}
.active-filters .chip:hover .chip-x{opacity:1}
.active-filters .chip-clear{
  background:none;color:var(--ink-3);border-color:var(--line)
}
.active-filters .chip-clear:hover{color:var(--ink);border-color:var(--line-2)}

.archive-empty{margin:40px 0 60px;color:var(--ink-2)}

/* ---- filter dialog ---- */
.filters-dialog{
  width:min(720px,calc(100vw - 40px));
  max-height:min(80vh,760px);
  margin:auto;padding:0;
  border:1px solid var(--line);border-radius:20px;
  background:var(--surface);color:var(--ink);
  box-shadow:var(--sh-lg);
  overflow:auto
}
.filters-dialog::backdrop{
  background:rgba(20,12,34,.42);
  backdrop-filter:blur(3px)
}
.filters-dialog .fd-head,
.filters-dialog .fd-foot{
  position:sticky;background:var(--surface);z-index:1;
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:18px 22px
}
.filters-dialog .fd-head{top:0;border-bottom:1px solid var(--line)}
.filters-dialog .fd-foot{bottom:0;border-top:1px solid var(--line)}
.filters-dialog .fd-head h2{
  margin:0;font-family:Fraunces,Georgia,serif;font-size:20px;font-weight:700
}
.fd-close{
  width:32px;height:32px;flex:none;border-radius:50%;cursor:pointer;
  display:grid;place-items:center;
  background:none;border:1px solid var(--line);color:var(--ink-2);
  font-size:19px;line-height:1
}
.fd-close:hover{border-color:var(--line-2);color:var(--ink)}
.filters-dialog .archive-filters{margin:0;padding:20px 22px}

/* ---- filters ---- */
.archive-filters{margin:22px 0 34px;display:grid;gap:12px}
.filter-row{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.filter-label{
  font:600 .72rem/1 Inter,system-ui,sans-serif;
  letter-spacing:.10em;text-transform:uppercase;
  color:var(--ink-3);min-width:96px
}
.archive-filters .chip{
  display:inline-flex;align-items:center;gap:6px;
  text-decoration:none;cursor:pointer;
  background:var(--surface);color:var(--ink-2);
  border:1px solid var(--line);
  transition:border-color .18s,color .18s,background .18s
}
.archive-filters .chip:hover{border-color:var(--line-2);color:var(--ink)}
.archive-filters .chip.is-active{
  background:var(--t-lilac);color:var(--lilac);border-color:transparent
}
/*
 * .85, not .65. At .65 the count blends to 3.1:1 on the chip's white ground —
 * it is small and semi-bold, so it needs 4.5:1, and .85 clears it while still
 * reading as secondary to the label beside it.
 */
.chip-n{
  font-size:.68rem;font-variant-numeric:tabular-nums;
  opacity:.85;padding-left:2px
}

/* ---- single article ---- */
.single-article{padding:44px 0 72px}

/*
 * The article sat in a 760px block inside the site's 1560px .wrap, which left
 * it stranded on a wide screen. It now shares the site container and splits
 * into a reading column and a sidebar of related columns. The grid is capped
 * rather than filling .wrap: at 1560px the text column alone would run past
 * 90 characters a line, which is unreadable in a serif at this size.
 */
.art-layout{
  display:grid;
  grid-template-columns:minmax(0,1fr) 320px;
  gap:clamp(34px,4.5vw,68px);
  align-items:start;
  max-width:1240px;
  margin:0 auto
}
.art-main{min-width:0}

/* ---- related columns ---- */
.art-side{min-width:0}
/* Nothing above the sidebar is sticky, so it can pin to the viewport top. */
.art-side-inner{position:sticky;top:24px}
.art-side-h{
  font:600 .72rem/1 Inter,system-ui,sans-serif;
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--ink-3);margin:0 0 16px;
  padding-bottom:14px;border-bottom:1px solid var(--line)
}
.relcards{display:grid;gap:12px}

.relcard{
  display:grid;
  grid-template-columns:76px minmax(0,1fr);
  gap:12px;align-items:start;
  padding:10px;
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:13px;
  text-decoration:none;
  transition:border-color .22s,box-shadow .22s,transform .22s cubic-bezier(.2,.8,.2,1)
}
.relcard:hover{
  border-color:var(--line-2);
  box-shadow:var(--sh-sm);
  transform:translateY(-2px)
}
/* A fixed tile here, unlike the archive grid — the sidebar has no room to let
   each clipping keep its own height. The thumbnail is decoration beside the
   headline rather than the record, so cropping it costs nothing. */
.relcard-pic{
  display:block;width:76px;height:76px;
  border-radius:9px;overflow:hidden;
  background:var(--paper);border:1px solid var(--line)
}
.relcard-pic img{display:block;width:100%;height:100%;object-fit:cover;object-position:top}
.relcard-b{display:block;min-width:0}
.relcard-t{
  display:block;
  font-family:Fraunces,Georgia,serif;font-weight:700;
  font-size:14px;line-height:1.34;color:var(--ink);
  margin:0 0 6px
}
.relcard-t:lang(hi){
  font-family:'Tiro Devanagari Hindi',Georgia,serif;
  font-weight:400;font-size:14.5px;line-height:1.55
}
.relcard-t:lang(pa){
  font-family:'Noto Sans Gurmukhi',system-ui,sans-serif;
  font-weight:600;font-size:13.5px;line-height:1.5
}
.relcard-m{
  display:block;
  font:500 11.5px/1.4 Inter,system-ui,sans-serif;
  color:var(--ink-3)
}
.relcard-m .undated{font-style:italic;opacity:.75}

.art-side-all{
  display:inline-block;margin-top:18px;
  font:600 .82rem/1.4 Inter,system-ui,sans-serif;
  color:var(--ink-2);text-decoration:none
}
.art-side-all:hover{color:var(--lilac)}

.art-head{margin-bottom:30px}
.art-pub{
  font:600 .74rem/1 Inter,system-ui,sans-serif;
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--lilac);margin:0 0 12px
}
.art-title{
  font-family:Fraunces,Georgia,serif;font-weight:900;
  font-size:clamp(1.9rem,4.4vw,3rem);line-height:1.12;
  letter-spacing:-.02em;color:var(--ink);margin:0
}
/* Devanagari needs more leading and no negative tracking to stay readable. */
.single-article:lang(hi) .art-title,
.art-title:lang(hi){
  font-family:'Tiro Devanagari Hindi',Fraunces,Georgia,serif;
  font-weight:400;line-height:1.35;letter-spacing:0
}
.art-subhead{
  font-family:Fraunces,Georgia,serif;font-size:1.12rem;line-height:1.5;
  color:var(--ink-2);margin:14px 0 0;font-style:italic
}
.art-subhead:lang(hi){font-family:'Tiro Devanagari Hindi',serif;font-style:normal}
.art-meta{
  font:500 .82rem/1.4 Inter,system-ui,sans-serif;
  color:var(--ink-3);margin:16px 0 0
}
.art-undated{font-style:italic;opacity:.8}

.art-body{
  font-family:Fraunces,Georgia,serif;
  font-size:1.06rem;line-height:1.72;color:var(--ink);
  max-width:68ch
}
.art-body:lang(hi),
.single-article:lang(hi) .art-body{
  font-family:'Tiro Devanagari Hindi',Georgia,serif;
  font-size:1.12rem;line-height:1.95
}
.art-body p{margin:0 0 1.15em}
.art-body h2{
  font-size:1.3rem;font-weight:700;margin:1.9em 0 .5em;color:var(--ink)
}
.art-body strong{font-weight:700}

/* ---- a post's own illustration ----
   The counterpart to .art-clip below, and deliberately the other way round:
   this sits above the body, so it takes a bottom margin rather than a top rule
   and does not announce itself as evidence of anything. */
.art-lead-img{margin:0 0 34px}
.art-lead-img img{
  width:100%;height:auto;border-radius:14px;
  border:1px solid var(--line);background:var(--surface)
}
.art-lead-img figcaption{
  font:500 .8rem/1.5 Inter,system-ui,sans-serif;
  color:var(--ink-3);margin-top:11px
}

/* ---- the clipping ---- */
.art-clip{margin:48px 0 0;padding-top:30px;border-top:1px solid var(--line)}
.art-clip img{
  width:100%;height:auto;border-radius:12px;
  border:1px solid var(--line);background:var(--surface)
}
.art-clip figcaption{
  font:500 .8rem/1.5 Inter,system-ui,sans-serif;
  color:var(--ink-3);margin-top:12px
}
.art-clip figcaption a{color:var(--sky)}

.art-nav{
  display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;
  margin-top:52px;padding-top:24px;border-top:1px solid var(--line);
  font:600 .86rem/1.4 Inter,system-ui,sans-serif
}
.art-nav a{color:var(--ink-2);text-decoration:none}
.art-nav a:hover{color:var(--lilac)}

/* ---- pagination ---- */
.pagination{
  display:flex;justify-content:center;gap:8px;flex-wrap:wrap;margin-top:44px
}
.pagination .page-numbers{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:40px;height:40px;padding:0 12px;border-radius:10px;
  font:600 .88rem/1 Inter,system-ui,sans-serif;text-decoration:none;
  color:var(--ink-2);background:var(--surface);border:1px solid var(--line)
}
.pagination .page-numbers:hover{border-color:var(--line-2);color:var(--ink)}
.pagination .page-numbers.current{
  background:var(--lilac);border-color:transparent;color:#fff
}
.pagination .dots{border:0;background:none}

/* ---- search ---- */
.search-form{display:flex;gap:10px;max-width:520px;margin:var(--page-gap) 0 0}
.search-form input{flex:1}

/* Below the two-column breakpoint the sidebar becomes a footer to the piece:
   full width, unpinned, and read after the column rather than beside it. */
@media (max-width:1080px){
  .art-layout{grid-template-columns:minmax(0,1fr);gap:0;max-width:820px}
  .art-side{margin-top:52px;padding-top:30px;border-top:1px solid var(--line)}
  .art-side-inner{position:static}
  .relcards{grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
}

@media (max-width:640px){
  .filter-label{min-width:0;width:100%}
  .art-clip{margin-top:36px}
  .relcards{grid-template-columns:minmax(0,1fr)}
}

/* ================================================================
   Clipping grid.

   A regular four-across grid, matching the home page's .clips row.

   The image FILLS the tile — the card is a way in to the piece, not a
   reader for it. The whole clipping is on the single, and the headline
   is printed as real text directly below, so the crop costs nothing that
   is not still on the card.

   Measured over the library, the clippings run 0.26 to 2.67 (median
   1.47) — so no tile ratio avoids cropping, and picking one is a trade,
   not a fix. At 16/9 the 82% of clippings taller than the tile crop
   vertically only; the 18% wider than it lose some width, and the widest
   keep about four fifths of it.

   object-position:top places the vertical crop at the BOTTOM, which is
   the half that matters: it is what keeps the masthead strip and the
   headline in frame on the tall portrait cuttings, and those are half
   the archive. Widen the tile to trade card height for fewer horizontal
   crops; centre the position and the portrait cuttings show their
   middle, which is body copy.
   ================================================================ */

.clipgrid{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  gap:20px;
  margin-top:var(--page-gap)
}
@media (max-width:1040px){ .clipgrid{grid-template-columns:repeat(2,1fr);gap:14px} }
@media (max-width:640px){ .clipgrid{grid-template-columns:1fr} }

.clipcard{
  display:flex;
  flex-direction:column;
  margin:0;
  background:var(--surface);
  border:1px solid var(--line);
  border-radius:15px;
  overflow:hidden;
  box-shadow:var(--sh-sm);
  text-decoration:none;
  transition:transform .26s cubic-bezier(.2,.8,.2,1),box-shadow .26s,border-color .26s
}
.clipcard:hover{
  transform:translateY(-4px);
  box-shadow:var(--sh-md);
  border-color:var(--line-2)
}
.clipcard .shot{
  display:block;
  aspect-ratio:16/9;
  background:var(--paper);
  border-bottom:1px solid var(--line);
  overflow:hidden
}
.clipcard .shot img{
  display:block;width:100%;height:100%;
  object-fit:cover;
  object-position:top
}
/* Fills the leftover space so every card in a row ends level. */
.clipcard .b{padding:13px 15px 15px;flex:1}
.clipcard .t{
  display:block;
  font-family:Fraunces,Georgia,serif;font-weight:700;
  font-size:15px;line-height:1.32;color:var(--ink);
  margin:0 0 7px
}
.clipcard .t:lang(hi){
  font-family:'Tiro Devanagari Hindi',Georgia,serif;
  font-weight:400;font-size:15.5px;line-height:1.55
}
.clipcard .ago{
  display:block;
  font:500 11.5px/1.4 Inter,system-ui,sans-serif;
  color:var(--ink-3)
}
.clipcard .undated{font-style:italic;opacity:.75}

/* The hero's lead picture had no rule at all: the <img> kept its intrinsic
   size inside a 21/8 box with overflow:hidden, so what showed was whatever
   happened to fall in the top-left corner — an accident, not a crop. Same
   fill and same top anchor as everything else. */
.leadpic img{
  display:block;position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  object-position:top
}

/* The hero's small 2x2 tiles fill the same way the archive grid does, and
   for the same reason: the card is a way in to the piece, not a reader for
   it, and the headline is printed as real text directly underneath. These
   tiles are wide and short, so the crop is almost entirely vertical —
   object-position:top keeps the masthead strip and the headline in frame. */
.rcard .pic img{
  width:100%;height:100%;
  object-fit:cover;
  object-position:top;
  background:var(--paper)
}

/* `.sechead` is now homepage-only (kicker + h2). Page-level headings go
   through `.pagehead` — see the page header block near the top of this file. */

/* ================================================================
   Chip contrast.

   The chips set their text to the full-strength brand hue on that hue's
   pale tint — e.g. --butter #D9930F on --t-butter #FEF2DA. Measured, every
   one of the six failed WCAG AA for normal text:

     sky 2.66:1   mint 2.24:1   coral 2.99:1
     butter 2.33:1   lilac 3.88:1   lime 2.69:1   (4.5:1 required)

   They are also 11.5px, bold, uppercase and letterspaced, which is the
   hardest case to read, so this was the worst place to be under target.

   The `-ink` variants below are the same hues darkened only until each
   clears 5:1 against its own tint. Backgrounds are untouched, so the
   pastel look is unchanged.
   ================================================================ */

:root{
  --sky-ink:#1467AB;     /* 5.13:1 on --t-sky    */
  --mint-ink:#1B7461;    /* 5.09:1 on --t-mint   */
  --coral-ink:#C02B13;   /* 5.04:1 on --t-coral  */
  --butter-ink:#8C5E06;  /* 5.09:1 on --t-butter */
  --lilac-ink:#6744E4;   /* 5.03:1 on --t-lilac  */
  --lime-ink:#40741B;    /* 5.13:1 on --t-lime   */
}

/* A touch less letterspacing and a hair more size — the tracking was doing
   as much damage to legibility at this size as the colour was. */
.hd-tags .chip{
  letter-spacing:.06em;
  font-size:12px;
}

/* ================================================================
   Hero CTA alignment.

   Both hero columns are centred flex columns of differing content height,
   so their buttons landed at different heights. `margin-top:auto` overrides
   justify-content for that one child and pins it to the bottom of each
   column; matching the bottom padding then puts the two buttons on the
   same baseline.
   ================================================================ */

.hero .cta{margin-top:auto}

.hero-recent .hero-more{
  margin-top:auto;
  align-self:flex-start
}

/* .hero-recent's bottom padding was slightly shallower than .hero-text's,
   which would leave the two buttons a few pixels out of line. */
.hero-recent{padding-bottom:clamp(28px,2.5vw,42px)}

@media (max-width:900px){
  /* Stacked on narrow screens there is no row to align to, so let the
     buttons sit directly under their own content. */
  .hero .cta,
  .hero-recent .hero-more{margin-top:18px}
}

/* ================================================================
   Punjabi.

   The corpus turned out not to be only Hindi and English — there is at
   least one ਨਵਾਂ ਜ਼ਮਾਨਾ clipping in Gurmukhi. Devanagari and Latin faces
   have no Gurmukhi coverage, so without this the text falls back to
   whatever the OS supplies, at the wrong weight and size.
   ================================================================ */

[lang="pa"]{
  font-family:'Noto Sans Gurmukhi',system-ui,sans-serif
}
.art-title:lang(pa),
.single-article:lang(pa) .art-title{
  font-family:'Noto Sans Gurmukhi',system-ui,sans-serif;
  font-weight:700;line-height:1.35;letter-spacing:0
}
.art-body:lang(pa),
.single-article:lang(pa) .art-body{
  font-family:'Noto Sans Gurmukhi',system-ui,sans-serif;
  font-size:1.04rem;line-height:1.9
}
.clipcard .t:lang(pa){
  font-family:'Noto Sans Gurmukhi',system-ui,sans-serif;
  font-weight:600;font-size:14.5px;line-height:1.5
}

/* Translated reprints and inferred publications — both are honest labels on
   the page rather than silent assumptions in the database. */
.art-translation{
  display:inline-block;
  font:600 .72rem/1 Inter,system-ui,sans-serif;
  letter-spacing:.08em;text-transform:uppercase;
  color:var(--mint-ink);background:var(--t-mint);
  padding:5px 11px;border-radius:999px;margin:14px 0 0
}
.art-inferred{
  font-size:.76rem;font-style:italic;color:var(--ink-3);
  border-bottom:1px dotted var(--line-2);cursor:help;margin-left:6px
}

/* ================================================================
   On Air
   ================================================================ */

/* ---- spacing ----

   The clips grid owns the gap above it, rather than inheriting it from
   whatever paragraph happens to precede it. base.css hangs that gap on
   `.band .sub{margin:0 0 34px}`, which held only as long as a `.sub` was
   always the last thing before the grid — it is not on /videos/, which
   opens with a `.pagehead`. So `.sub` keeps no bottom margin and `.clips`
   carries the gap, the same `--page-gap` every other listing uses. */
.clips{margin-top:var(--page-gap)}
.band .sub{margin-bottom:0}

/* ---- paper, not a full-bleed dark page ----

   /videos/ and a single clip used to carry `.band` across the whole page.
   The dark ground earns its keep on the homepage, where it lifts one section
   out of a long light scroll; on a page of its own there is nothing to lift
   it out of, and it just made On Air the one part of the site that looked
   like a different site.

   `.band` is therefore homepage-only now, and `.band-page` — the full-bleed
   dark page it used to sit on — is gone entirely. The clip cards
   were drawn against that dark ground, so what follows re-grounds them on
   paper — the same surface, hairline and shadow every other card on the
   site uses, rather than a second card design. */
.clips-paper .clip{
  background:var(--surface);
  border-color:var(--line);
  box-shadow:var(--sh-sm)
}
.clips-paper .clip:hover{
  background:var(--surface);
  border-color:var(--line-2);
  box-shadow:var(--sh-md)
}

/* Behind the still: `rgba(0,0,0,.35)` is a hole punched in a white card.
   It shows only where a clip has no thumbnail at all. */
.clips-paper .clip .shot{background:var(--paper)}

.clips-paper .clip .clip-t{color:var(--ink)}
.clips-paper .clip:hover .clip-t{color:var(--lilac)}

/* ================================================================
   Clip cards.

   .clip is a column, not a plain block: the grid stretches every card in
   a row to the tallest, and without this the body of a one-line card
   stopped short of the card's own bottom edge.

   The display declarations on .shot and .body are deliberate. base.css
   gives .shot an aspect-ratio and .body vertical padding, and neither
   applies to a non-replaced inline box — so if these ever go back to
   being spans the still silently collapses to nothing again.
   ================================================================ */

.clip{
  text-decoration:none;
  display:flex;flex-direction:column
}
.clip .shot{display:block;flex:none;background:rgba(0,0,0,.35)}
.clip .body{display:flex;flex-direction:column;gap:2px;flex:1}
.clip .shot img{
  display:block;
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover
}
.clip:hover .play{transform:scale(1.09)}

/* The band is dark, but the site's hues were picked for paper. On --deep they
   measure 2.6:1 (lilac) to 4.6:1, and the channel name is 11px bold uppercase
   — the worst case to read. Re-point the six inside the band to brighter
   values chosen against exactly this ground.

   The `-ink` pair follows, because the channel name asks for `--x-ink` now:
   those are the hues darkened for paper (see the chip-contrast block), and a
   5:1-on-white red on --deep is the same mistake in the other direction. On
   this ground the bright hue is the legible one, so they resolve back to it. */
.band{
  --mint:#5FE0C2; --sky:#79C4FA; --lilac:#AE96FF;
  --butter:#FFC960; --coral:#FF9280; --lime:#9BDD5E;

  --mint-ink:var(--mint); --sky-ink:var(--sky); --lilac-ink:var(--lilac);
  --butter-ink:var(--butter); --coral-ink:var(--coral); --lime-ink:var(--lime)
}

/* Marks a clip that lives on YouTube rather than being self-hosted. */
.clip-src{
  position:absolute;right:9px;bottom:9px;
  font:700 9.5px/1 Inter,system-ui,sans-serif;letter-spacing:.1em;
  text-transform:uppercase;color:#fff;
  background:rgba(0,0,0,.62);padding:4px 7px;border-radius:5px
}

.band-more{margin:clamp(34px,3vw,48px) 0 0;display:flex;justify-content:center}

/* Same problem as the hues: .btn.ghost is drawn for paper, so on the band it
   landed ink-on-ink — "All 13 appearances" was dark purple on dark purple and
   all but invisible. (The band's pagination override that used to sit here
   went with /videos/: the homepage band shows four clips and this button, and
   never paginates.) */
.band .btn.ghost{color:#FBF9FF;border-color:rgba(255,255,255,.28)}
.band .btn.ghost:hover{color:var(--lilac);border-color:var(--lilac)}
@media (max-width:1000px){ .clips{grid-template-columns:repeat(2,1fr)} }
@media (max-width:560px){ .clips{grid-template-columns:1fr} }

/* ---- single clip ---- */

/* A `<section>`, so it was taking `section{padding:76px 0 0}` — 76px of air
   above and none at all below the previous/next links. Every other single on
   the site is `.single-article`; this matches it. */
.single-clip{padding:44px 0 72px}

.single-clip .clip-title{
  font-family:Fraunces,Georgia,serif;font-weight:900;
  font-size:clamp(22px,3vw,34px);line-height:1.15;color:var(--ink);margin:10px 0 22px
}
.single-clip .clip-title:lang(hi){
  font-family:'Tiro Devanagari Hindi',serif;font-weight:400;line-height:1.4
}

.ytlite,.clip-video{
  width:100%;aspect-ratio:16/9;border-radius:14px;overflow:hidden;
  background:#000;display:block;position:relative
}
.ytlite iframe{width:100%;height:100%;border:0;display:block}
.ytlite-btn{
  all:unset;display:block;position:absolute;inset:0;cursor:pointer
}
.ytlite-btn img{width:100%;height:100%;object-fit:cover}
.ytlite-btn .play{pointer-events:none}
.ytlite-btn:hover .play{transform:scale(1.09)}
.ytlite-btn:focus-visible{outline:3px solid var(--sky);outline-offset:3px}

.clip-off{margin:14px 0 0;font:500 .85rem/1.4 Inter,system-ui,sans-serif}
.clip-off a{color:var(--ink-3)}
.clip-off a:hover{color:var(--lilac)}

/* The same measure and face as `.art-body` — a clip's description is read the
   way a column is. `.art-nav` needs no override at all now: its own rule is
   already drawn for paper. */
.clip-body{
  margin-top:26px;color:var(--ink);max-width:68ch;
  font-family:Fraunces,Georgia,serif;font-size:1.06rem;line-height:1.72
}
.clip-body:lang(hi){
  font-family:'Tiro Devanagari Hindi',Georgia,serif;
  font-size:1.12rem;line-height:1.95
}

/* ================================================================
   Homepage writing column.

   .feature .pic and .rows .th are fixed-ratio windows (16/9 and 16/11)
   drawn for the static build's generated artwork. The clipping fills
   them, as it does everywhere else on the site — a letterboxed cutting
   in a 16/9 window is a thin strip of newsprint in a field of tint, and
   it reads as a broken image rather than as a card.

   Nothing is lost by the crop that is not still on the card: the whole
   clipping is on the single, and the headline is set as real text
   beside or below the picture here.

   object-position:top is what makes the crop survivable. Most cuttings
   are portrait, so the crop is vertical, and the top is the half that
   carries the masthead strip and the headline. Centre it and the
   portrait ones show their middle, which is body copy.
   ================================================================ */

.feature .pic img,
.rows .th img{
  position:absolute;inset:0;
  width:100%;height:100%;
  object-fit:cover;
  object-position:top
}

/* Devanagari headlines need the leading the Latin ones do not. */
.feature h3:lang(hi),
.rows h4:lang(hi){
  font-family:'Tiro Devanagari Hindi',Georgia,serif;
  font-weight:400;line-height:1.5
}
.feature h3:lang(pa),
.rows h4:lang(pa){
  font-family:'Noto Sans Gurmukhi',system-ui,sans-serif;
  font-weight:600;line-height:1.45
}
.feature p:lang(hi){font-family:'Tiro Devanagari Hindi',Georgia,serif;line-height:1.85}
.feature p:lang(pa){font-family:'Noto Sans Gurmukhi',system-ui,sans-serif;line-height:1.8}

/* ================================================================
   Books.

   The .book panel itself comes from base.css, ported from the static
   build. What follows is only what the WordPress pages added: a book's
   own page, the listing, the reviews and the launch gallery.
   ================================================================ */

/* base.css styles `.book h2`. The book's own page puts an h1 there — it is
   the page's title — so give it the same treatment rather than demoting
   the heading to fit the stylesheet. */
.book h1{font-size:clamp(26px,4vw,42px);margin:14px 0 8px;line-height:1.14}
.book h1:lang(hi),
.book h2:lang(hi){
  font-family:'Tiro Devanagari Hindi',Georgia,serif;
  font-weight:400;line-height:1.4
}
.book h1 a,.book h2 a{color:inherit;text-decoration:none}
.book h2 a:hover{color:var(--coral)}
.book p:lang(hi),.book .subt:lang(hi){
  font-family:'Tiro Devanagari Hindi',Georgia,serif;line-height:1.95
}

.book-actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:4px}

/* Publisher and ISBN: reference, not sales copy, so they sit quietly under
   the buttons rather than competing with them. */
.book-facts{
  display:flex;flex-wrap:wrap;gap:10px 34px;
  margin:26px 0 0;padding-top:20px;border-top:1px solid var(--line)
}
.book-facts dt{
  font:600 .68rem/1 Inter,system-ui,sans-serif;
  letter-spacing:.12em;text-transform:uppercase;color:var(--ink-3)
}
.book-facts dd{margin:6px 0 0;font-size:14.5px;color:var(--ink-2)}

/* ---- /books/ ---- */
.booklist{display:grid;gap:34px;margin-top:var(--page-gap)}

/* ---- a book's own page ----

   The description is set in two columns on a wide screen rather than one
   centred ribbon. A single column at a readable measure leaves two thirds
   of the page empty beside it, and widening that one column past ~75
   characters trades the empty space for lines too long to track back.
   Two columns spend the width and keep each line around 55 characters.

   .art-body caps itself at 66ch for the single-article page; that cap is
   lifted here and the measure comes from the column width instead. Below
   1040px there is no width to spend, so it collapses to one column and
   the 66ch-equivalent cap comes back. */
.bookpage .book-body{
  margin-top:22px;
  max-width:none
}
@media (min-width:1041px){
  .bookpage .book-body{
    columns:2 340px;
    column-gap:clamp(38px,4vw,72px);
    orphans:2;
    widows:2
  }
  /* A heading would otherwise be left stranded at the foot of column one. */
  .bookpage .book-body h2,
  .bookpage .book-body h3{break-after:avoid}
}
@media (max-width:1040px){
  .bookpage .book-body{max-width:66ch}
}
.bookpage .art-nav{margin-top:0}

/* ================================================================
   Reviews.

   Two columns, not the four-up clipping grid: these are read for their
   text, and a review is a paragraph rather than a headline.
   ================================================================ */

.revgrid{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));
  gap:22px;margin-top:26px
}

.revcard{
  display:flex;gap:18px;
  background:var(--surface);border:1px solid var(--line);
  border-radius:var(--r);padding:18px;box-shadow:var(--sh-sm);
  transition:transform .26s cubic-bezier(.2,.8,.2,1),box-shadow .26s,border-color .26s
}
.revcard:hover{transform:translateY(-4px);box-shadow:var(--sh-md);border-color:var(--line-2)}

/* The cutting is a thumbnail beside the text here, not the record, so it
   fills the tile like every other card on the site. The tile is portrait
   and so are most cuttings, so object-position:top keeps the masthead and
   headline rather than the middle of the body copy. */
.revshot{
  flex:none;width:104px;height:136px;
  border-radius:10px;overflow:hidden;border:1px solid var(--line);
  background:var(--paper);display:block
}
.revshot img{
  width:100%;height:100%;display:block;
  object-fit:cover;
  object-position:top
}

.revbody{min-width:0}
.revpub{
  font:600 .7rem/1 Inter,system-ui,sans-serif;
  letter-spacing:.12em;text-transform:uppercase;color:var(--coral);margin:0 0 9px
}
.revbody h3{font-size:17px;line-height:1.3;margin:0 0 9px}
.revbody h3:lang(hi){
  font-family:'Tiro Devanagari Hindi',Georgia,serif;
  font-weight:400;font-size:17.5px;line-height:1.55
}
.revbody h3 a{color:inherit;text-decoration:none}
.revcard:hover h3 a{color:var(--lilac)}
.revsnip{
  margin:0 0 10px;font-size:14px;line-height:1.65;color:var(--ink-2)
}
.revsnip:lang(hi){font-family:'Tiro Devanagari Hindi',Georgia,serif;line-height:1.9}
.revmeta{margin:0;font:500 12px/1.45 Inter,system-ui,sans-serif;color:var(--ink-3)}

/* "A review of <book>" on a single review. */
.art-about{
  font:500 .92rem/1.5 Inter,system-ui,sans-serif;
  color:var(--ink-2);margin:14px 0 0
}
.art-about a{color:var(--lilac);font-weight:600}

@media (max-width:520px){
  .revcard{flex-direction:column}
  .revshot{width:100%;height:190px}
}

/* ================================================================
   Launch gallery.

   Columns rather than a fixed grid, for the same reason the clipping
   archive uses them: event photographs arrive in whatever shape the
   photographer shot them, and a cover-cropped tile would cut people out
   of the frame. Captions are printed under each photograph because they
   name the people in it.
   ================================================================ */

.gal{columns:3 280px;column-gap:20px;margin-top:26px}
@media (max-width:900px){ .gal{columns:2 200px;column-gap:14px} }

.galitem{
  break-inside:avoid;margin:0 0 20px;
  background:var(--surface);border:1px solid var(--line);
  border-radius:15px;overflow:hidden;box-shadow:var(--sh-sm);
  transition:transform .26s cubic-bezier(.2,.8,.2,1),box-shadow .26s,border-color .26s
}
.galitem:hover{transform:translateY(-4px);box-shadow:var(--sh-md);border-color:var(--line-2)}
.galitem img{display:block;width:100%;height:auto}
.galitem figcaption{
  padding:12px 14px 14px;
  font:500 12.5px/1.55 Inter,system-ui,sans-serif;color:var(--ink-3)
}
.galzoom{display:block;position:relative;cursor:zoom-in}

/* ---- lightbox ----
   A native <dialog>, like the archive's filter panel, so Escape, the focus
   trap and the backdrop come for free. Built by site.js: with JavaScript
   off each thumbnail is still a plain link to the full-size image. */
.lightbox{
  border:0;padding:0;background:transparent;
  max-width:96vw;max-height:96vh;width:auto;color:#fff
}
.lightbox::backdrop{background:rgba(15,12,28,.88)}
.lightbox figure{margin:0;display:flex;flex-direction:column;gap:12px;align-items:center}
.lightbox img{
  max-width:96vw;max-height:82vh;width:auto;height:auto;
  border-radius:12px;display:block;background:#000
}
.lightbox figcaption{
  font:500 13.5px/1.6 Inter,system-ui,sans-serif;
  color:rgba(239,234,251,.86);text-align:center;max-width:70ch;padding:0 12px
}
.lb-btn{
  position:absolute;top:50%;transform:translateY(-50%);
  width:44px;height:44px;border-radius:50%;border:0;cursor:pointer;
  background:rgba(255,255,255,.14);color:#fff;font-size:20px;line-height:1;
  display:grid;place-items:center;transition:background .2s
}
.lb-btn:hover{background:rgba(255,255,255,.3)}
.lb-btn:focus-visible{outline:3px solid var(--sky);outline-offset:2px}
.lb-prev{left:10px}
.lb-next{right:10px}
.lb-close{
  position:absolute;top:10px;right:10px;transform:none;
  width:40px;height:40px;font-size:22px
}
.lb-count{
  position:absolute;top:18px;left:16px;
  font:600 12px/1 Inter,system-ui,sans-serif;letter-spacing:.08em;
  color:rgba(239,234,251,.7)
}

/* ================================================================
   About — the page, and the short version on the homepage.

   base.css already styles .about, .about-photo and .tl for the static
   build's single homepage section. What is added here is everything the
   full page needs on top: an h1 rather than an h2, prose coming out of
   the editor, and a timeline carrying a role, an employer and a body
   instead of one line of text.
   ================================================================ */

.about h1{font-size:clamp(25px,3.6vw,38px);margin:12px 0 18px}

/* ---- the biography, straight out of the block editor ---- */

.about-body h2{
  font-family:Fraunces,Georgia,serif;font-weight:700;
  font-size:1.22rem;color:var(--ink);
  margin:34px 0 14px
}
.about-body ul{
  columns:2 220px;column-gap:34px;
  list-style:none;margin:0;padding:0
}
.about-body ul li{
  break-inside:avoid;
  position:relative;padding:0 0 10px 20px;
  color:var(--ink-2);font-size:14.5px;line-height:1.55
}
/* A dash rather than a bullet — these are competencies, not steps. */
.about-body ul li::before{
  content:"";position:absolute;left:0;top:.62em;
  width:10px;height:2px;border-radius:2px;background:var(--mint)
}
.about-body a{color:var(--lilac);text-decoration:underline;text-underline-offset:3px}

/* ---- the career timeline ---- */

.about-career{padding-top:58px}
.career-split{
  display:grid;grid-template-columns:.8fr 1.2fr;gap:52px;align-items:start
}
.career-split .tl{margin-top:0}
@media (max-width:900px){
  .career-split{grid-template-columns:1fr;gap:28px}
}

/* A role still held gets a filled dot; a closed one stays an outline. */
.tl li.is-current::before{background:var(--c,var(--lilac))}

.tl-full li{padding-bottom:30px}
.tl-role{
  font-family:Fraunces,Georgia,serif;font-weight:700;
  font-size:17.5px;line-height:1.3;color:var(--ink);
  margin:1px 0 3px
}
.tl-role:lang(hi){font-family:'Tiro Devanagari Hindi',Georgia,serif;font-weight:400;line-height:1.5}
.tl-org{margin:0;font-size:13.5px;color:var(--ink-3)}
.tl-body{margin-top:10px;max-width:66ch}   /* the same measure .about p keeps */
.tl-body p{margin:0 0 9px;font-size:14.5px;line-height:1.66;color:var(--ink-2)}
.tl-body p:last-child{margin-bottom:0}

/* ================================================================
   HERO — two leads and the recent grid.

   The card used to be a lead column and four cards. It carries the newest
   broadcast as well now, and as a lead rather than a footnote: same
   picture, same headline size, same call to action, in a column of its
   own. 35 / 35 / 30 — the two leads matched to each other, and the recent
   grid taking what is left.
   ================================================================ */

.hero-card-3{grid-template-columns:35fr 35fr 30fr}

/* Down a step from the two-column card: the headline has two thirds of the
   width it had, and the standfirst came out with it (see front-page.php) so
   both leads fit above the fold on a laptop. */
.hero-card-3 .hero-text h1,
.hero-card-3 .hero-onair h2{
  font-size:clamp(21px,1.75vw,29px);margin:12px 0 12px;max-width:22ch
}
.hero-card-3 .hero-onair h2{font-variation-settings:"opsz" 100}
/* Both pictures keep one ratio rather than each taking its column's slack.
   Letting them flex made their heights depend on how many lines the headline
   under them ran to, which put the two kickers on different lines — the one
   thing two leads side by side must not do. Equal columns and one ratio means
   equal heights, so "Latest column" and "Latest on air" start level whatever
   the headlines do. Taller than the old 21/8 strip, which is what leaves the
   columns near the height of the grid opposite. */
.hero-card-3 .leadpic{
  flex:none;aspect-ratio:4/3;
  max-height:clamp(240px,23vw,392px);margin-bottom:18px
}

/* The slack goes under the meta line instead, so the three columns still end
   level and the two buttons sit on the same line — a one-line headline beside
   a three-line one would otherwise float its button half a column up. */
.hero-card-3 .hero-text{justify-content:flex-start}
.hero-card-3 .cta{margin-top:auto;padding-top:22px}

/* The three columns are divided the same way the two were. */
.hero-onair{border-left:1px solid var(--line)}

/* A narrower column than the one this padding was written for. */
.hero-card-3 .hero-recent{
  padding-left:clamp(20px,1.6vw,28px);padding-right:clamp(20px,2vw,34px);
  /* So the column reports the height of its kicker and button, and the grid
     between them fills whatever the two leads have set. */
  min-height:0
}
/* The grid takes the slack, not the button's auto margin. With three columns
   the two leads are the taller pair, and `.hero-more{margin-top:auto}` put all
   of that difference in one gap above the button. The rows share the height
   instead, and the stills inside the cards absorb it — so the spacing above
   and below the grid is the same 18px whatever the column next to it does. */
.hero-card-3 .rgrid{
  gap:11px;flex:1 1 0;min-height:0;margin:18px 0;
  /* minmax(0,…), not 1fr: a bare 1fr floors the row at its content, which is
     how the grid ended up taller than the leads it should be sizing to. */
  grid-template-rows:minmax(0,1fr) minmax(0,1fr)
}
/* It is the text block that gets the fixed height here, not the still.

   Two things had to hold at once: the four cards start their text on the same
   line, and the grid never makes the card taller than the two leads beside it.
   Fixing the still broke the first (its height then followed whether the title
   under it ran to two lines or three); giving it a percentage of the card
   broke the second — a percentage makes the row at least `text / (1 - pct)`
   tall, which is a floor the leads could not reach, so the grid started
   driving the height of the whole hero.

   A fixed text block does both. The rows are equal, so still = row - text is
   equal too: the titles line up, the mastheads line up under them, and the
   stills still take up whatever slack the column has. The row's floor is the
   text block alone, which is short enough that the leads keep setting the
   height. */
/* flex-basis 0, not auto — this is what blew the panel up. `.rcard .pic img`
   is sized `height:100%`, which against an auto-height parent falls back to
   the file's own height: a full newspaper page, 300px and more of it. With
   the still's basis at 0 it contributes nothing to how tall the column wants
   to be and only grows into what is left, and the image is taken out of flow
   the way `.leadpic img` already is so it cannot report a height at all. */
.hero-card-3 .rcard .pic{flex:1 1 0;height:auto;min-height:clamp(78px,6.5vw,112px)}
.hero-card-3 .rcard .pic img{position:absolute;inset:0}
.hero-card-3 .rcard .b{flex:none;height:clamp(102px,8.4vw,126px);overflow:hidden}
.hero-card-3 .hero-recent .hero-more{margin-top:0}

/* The still is a picture and a play button; .leadpic is the frame both leads
   share, so the button positions against it rather than a clip-only box. */
.leadpic .play{width:44px;height:44px}
.leadpic a:hover .play{transform:scale(1.12)}

/* .leadpic anchors its crop to the top, which is right for a column's
   artwork. A broadcast still puts the panel across the middle of the
   frame, so this one crops from the centre. */
.hero-onair .leadpic img{object-position:center}

/* Two leads side by side with the grid under them, before the whole card
   stacks. Below 1040px base.css already collapses .hero-card to one column;
   this only has to say what the third column does on the way there. */
@media(max-width:1240px){
  .hero-card-3{grid-template-columns:1fr 1fr}
  .hero-card-3 .hero-recent{
    grid-column:1 / -1;border-left:0;border-top:1px solid var(--line)
  }
  /* Everything above sizes this column against the two leads beside it: the
     grid takes the slack at flex-basis 0, its rows are minmax(0,1fr), and the
     card's text block is a fixed height. Stacked there are no leads to match
     and no slack to take, so flex-basis 0 leaves the grid nothing to hand its
     rows, both resolve to zero, and .rcard's overflow:hidden clips the cards
     to the lines their borders draw — the "Most recent" list rendered as four
     empty rules. Back to the natural flow base.css already describes. */
  .hero-card-3 .rgrid{flex:none;min-height:auto;grid-template-rows:none}
  .hero-card-3 .rcard .pic{flex:none;height:clamp(70px,6vw,92px);min-height:0}
  .hero-card-3 .rcard .b{flex:1;height:auto;overflow:visible}
}
@media(max-width:1040px){
  .hero-card-3{grid-template-columns:1fr}
  .hero-onair{border-left:0;border-top:1px solid var(--line)}
}

/* ---- the homepage's short version ---- */

/* About holds the left half of the homepage split, with @STBA on the right.
   The panel is the taller of the two, so the column stretches to match it
   and the figures band is pushed to the foot — the two columns then end on
   the same line instead of the figures floating halfway up. The gap is the
   floor under that push, so the band never crowds "The full story" on a
   viewport where the two columns happen to come out level. */
.about-col{display:flex;flex-direction:column;gap:44px;align-self:stretch}
.about-col .stats{margin-top:auto}

/* The portrait is floated rather than given a grid column of its own: the
   heading and the opening paragraph sit beside it, and everything past its
   bottom edge — the second paragraph and the button — runs the full width
   of the column instead of staying in a narrow measure with dead space to
   its left. flow-root so the float is contained if the copy ever comes out
   shorter than the photograph. */
.about-intro{display:flow-root}
.about-intro-photo{float:left;width:210px;margin:4px 32px 10px 0}
.about-intro-photo img{
  display:block;width:100%;aspect-ratio:3/3.75;
  object-fit:cover;object-position:center 16%;
  border-radius:20px;box-shadow:var(--sh-md)
}
.about-intro h2{font-size:clamp(23px,2.7vw,31px);margin:11px 0 0;line-height:1.16}
.about-intro-copy{margin:16px 0 22px}
.about-intro-copy p{color:var(--ink-2);font-size:15.5px;line-height:1.75;margin:0 0 13px}
.about-intro-copy p:last-child{margin-bottom:0}
/* The same treatment prose links get on the About page itself. */
.about-intro-copy a{color:var(--lilac);text-decoration:underline;text-underline-offset:3px}

/* Four figures in half the width read as two rows of two. Only above the
   1040px breakpoint — below it the split is already one column, and the
   base stylesheet's own steps down to two and then one are what should
   apply. */
@media(min-width:1041px){
  .stats-half{grid-template-columns:1fr 1fr}
}

/* One column, and nothing left to bottom-align against. */
@media(max-width:1040px){
  .about-col{gap:36px}
  .about-intro-photo{width:236px}
}
/* Too narrow to wrap around anything — the photograph takes its own line. */
@media(max-width:560px){
  .about-intro-photo{float:none;width:100%;max-width:230px;margin:0 0 22px}
}

@media (max-width:640px){
  .about-body ul{columns:1}
}

/* ================================================================
   Invite to Speak — the contact page.

   Almost everything here is borrowed rather than invented: `.stats` for
   the figures band, `.pubs` for the subjects, `.about-body` for the prose
   out of the editor. What is genuinely new is the form, which the static
   build only ever had as a single email box.
   ================================================================ */

.invite{padding-bottom:20px}

/* ---- the opening: header and intro on the left, him on the right ----

   The header and the prose measure under 70ch, which on the site's 1560px
   wrap left the whole right half of the page empty above the figures. */
.invite-intro{
  display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,.75fr);
  gap:clamp(32px,4vw,68px);align-items:center
}
.invite-intro-text{min-width:0}

/* The source is a 960px event photograph cropped to him at the lectern, so
   it is capped at a size it can actually fill rather than blown up to the
   column. `justify-self:center` then keeps it centred in the space it does
   not use. */
.invite-photo{
  margin:0;position:relative;
  max-width:400px;width:100%;justify-self:center
}
.invite-photo img{
  display:block;width:100%;height:auto;position:relative;z-index:1;
  border-radius:22px;box-shadow:var(--sh-md)
}
/* The same tinted card the About portrait sits on, mirrored. That one is the
   left column and throws its wash right, toward the text; this one is the
   right column, so it throws left, toward the text again. */
.invite-photo::before{
  content:"";position:absolute;inset:-14px 14px 26px -14px;
  border-radius:26px;z-index:0;
  background:linear-gradient(145deg,var(--lilac),var(--sky) 50%,var(--mint));
  opacity:.5
}

@media (max-width:1000px){
  .invite-intro{grid-template-columns:1fr;gap:34px}
  /* Beneath the prose it is a picture on a page rather than half the
     composition, so it stops competing with the heading for width. */
  .invite-photo{max-width:320px;justify-self:start}
  .invite-photo::before{inset:-12px 12px 22px -12px}
}

.invite-lead{margin-top:var(--page-gap);max-width:70ch}
.invite-lead p{color:var(--ink-2);font-size:16px;line-height:1.78;margin:0 0 15px}

/* Six tiles, not four. In `.stats`' four-across grid the last two would sit
   alone on a second row looking like an afterthought; three-across gives two
   even rows. The tiles themselves are unchanged. */
.invite-figures{grid-template-columns:repeat(3,1fr);margin-top:46px}
.invite-figures .stat{padding:26px 20px}
.invite-figures .l{font-size:12.5px}

.invite-topics{margin-top:34px}

/* Eight subjects rather than the homepage band's dozen mastheads, and they
   want to be one row: a wrap that leaves a single subject alone on a second
   line reads as an afterthought rather than the eighth of eight. A step down
   in size and a tighter gap is what fits them on one line at desktop widths;
   below that they wrap as the band always has. */
.invite-topics .names{gap:9px 21px}
.invite-topics .names span{opacity:.86;font-size:clamp(14.5px,1.25vw,17.5px)}
.invite-topics .names a{color:inherit;transition:color .2s,opacity .2s}
.invite-topics .names a:hover{color:var(--lilac)}

/* ---- the form and its sidebar ---- */

/* `align-items:start` left the sidebar as tall as its own two cards and no
   more, so it stopped a long way above the foot of the form and the pair
   read as unfinished. Stretched, the two columns end level; the aside is a
   flex column and its last card takes the slack, so the growth lands in one
   card rather than being shared out into two half-empty ones. */
.invite-split{
  display:grid;grid-template-columns:1.35fr .85fr;gap:34px;
  align-items:stretch;margin-top:56px
}

.eform-card{
  background:radial-gradient(closest-side at 12% 0%,var(--t-lilac),transparent 70%),var(--surface);
  border:1px solid var(--line);border-radius:26px;
  padding:38px 36px 34px;box-shadow:var(--sh-sm)
}
.eform-card h2{font-size:clamp(23px,2.6vw,31px);margin:13px 0 10px}
.eform-lede{color:var(--ink-2);font-size:15px;line-height:1.68;margin:0 0 26px;max-width:52ch}

/* Nothing was sent, so this has to read as a stop rather than a tint. */
.eform-alert{
  margin:0 0 22px;padding:13px 16px;border-radius:12px;
  background:var(--t-coral);color:var(--coral-ink);
  border:1px solid color-mix(in srgb,var(--coral) 40%,transparent);
  font-size:14px;line-height:1.5
}

/* Off-screen rather than display:none — a field a bot can see is the whole
   point of it, and `hidden`/`display:none` is exactly what they skip. */
.eform-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

.eform-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px 18px}
.efield{margin:0;display:flex;flex-direction:column;gap:7px;min-width:0}
.efield-wide{grid-column:1 / -1}
.efield label{
  font-size:12px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:var(--ink-3)
}
.efield .req{
  text-transform:none;letter-spacing:0;font-weight:500;font-size:11.5px;
  color:var(--coral);margin-left:6px
}
.efield input,
.efield select,
.efield textarea{
  width:100%;padding:12px 15px;border-radius:12px;
  border:1px solid var(--line-2);background:var(--paper);color:var(--ink);
  font-family:inherit;font-size:15px;line-height:1.5;
  transition:border-color .18s,box-shadow .18s
}

/* The select shared the rule above but not the result: left at `appearance:
   auto` the browser draws its own control, which on macOS meant a white box
   a few pixels shorter than the cream inputs it sat beside, with its own
   idea of the padding. Turning the native chrome off makes the declarations
   above actually apply, and the arrow is drawn back on as a background — an
   inline SVG data URI so it needs no extra request and picks up the same
   ink as the label. `min-height` matches the computed height of a text
   input (12 + 12 padding + 1.5 × 15px line + 2 borders) so the two line up
   exactly rather than approximately. */
.efield select{
  -webkit-appearance:none;appearance:none;
  min-height:47px;
  padding-right:40px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235B5379' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-size:17px 17px
}
/* Firefox keeps a focus ring inside the control and tints the option list. */
.efield select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--ink)}

.efield textarea{resize:vertical;min-height:130px}
.efield input:focus,
.efield select:focus,
.efield textarea:focus{
  outline:none;border-color:var(--lilac);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--lilac) 22%,transparent)
}
.efield [aria-invalid="true"]{border-color:var(--coral)}
.efield-err{font-size:12.5px;color:var(--coral);line-height:1.45}

/* Safari renders date inputs shorter than text ones and iOS shrinks any
   control under 16px by zooming the page at it. */
.efield input[type="date"]{min-height:47px}
@media (max-width:640px){
  .efield input,.efield select,.efield textarea{font-size:16px}
}

.eform-foot{
  display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  margin-top:26px;padding-top:24px;border-top:1px solid var(--line)
}
.eform-note{margin:0;flex:1 1 260px;font-size:12.5px;line-height:1.55;color:var(--ink-3)}

/* ---- the sidebar cards ---- */

.invite-aside{display:flex;flex-direction:column;gap:20px}
.invite-aside .icard:last-child{flex:1}
.icard{
  background:var(--surface);border:1px solid var(--line);
  border-radius:22px;padding:26px 26px 28px;box-shadow:var(--sh-sm)
}
.icard h3{font-size:19px;margin:0 0 16px}

.icard-list{list-style:none;margin:0;padding:0;display:grid;gap:13px}
.icard-list li{display:grid;gap:2px;font-size:14.5px;line-height:1.5;word-break:break-word}
.icard-k{
  font-size:11px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--ink-3)
}
.icard-list a{color:var(--lilac);text-decoration:underline;text-underline-offset:3px}

/* .socials hides itself on small screens — it is decoration in the masthead.
   Here it is the only route to his profiles, so it stays. */
.icard-soc{display:flex;gap:8px;margin-top:20px;padding-top:18px;border-top:1px solid var(--line)}
.icard-soc a{
  width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  background:var(--t-lilac);color:var(--lilac);
  transition:transform .2s,filter .2s
}
.icard-soc a:hover{transform:translateY(-2px);filter:brightness(.94)}
.icard-soc svg{width:15px;height:15px;fill:currentColor}

.iformats{list-style:none;margin:0;padding:0;display:grid;gap:16px}
.iformats li{
  display:grid;gap:4px;padding-left:16px;position:relative;
  font-size:13.5px;line-height:1.6;color:var(--ink-2)
}
.iformats li::before{
  content:"";position:absolute;left:0;top:.55em;
  width:7px;height:7px;border-radius:50%;background:var(--mint)
}
.iformats b{font-size:14.5px;color:var(--ink);font-weight:600}

/* ---- responsive ---- */

@media (max-width:1100px){
  .invite-split{grid-template-columns:1fr;gap:26px}
  /* Two side by side, so the pair does not stretch across the full width. */
  .invite-aside{flex-direction:row}
  .invite-aside .icard{flex:1 1 0;min-width:0}
}
@media (max-width:1040px){
  .invite-figures{grid-template-columns:1fr 1fr}
}
@media (max-width:760px){
  .invite-aside{flex-direction:column}
  .eform-card{padding:30px 22px 26px}
  .icard{padding:22px 20px 24px}
}
@media (max-width:640px){
  .invite-figures{grid-template-columns:1fr}
  .eform-grid{grid-template-columns:1fr}
}

/* ================================================================
   THE GALLERY  /photos/
   ----------------------------------------------------------------
   Columns, not a grid, and for the reason set out on the book page:
   photographs arrive in whatever shape the photographer shot them.
   Measured over the 117 in the first import they run 0.66 to 2.22,
   with a median of 1.50 — so no single tile ratio fits, and a
   cover-crop would cut somebody out of about half of them.

   This is the opposite decision to the clipping cards, which DO crop
   to a fixed ratio with `object-position:top`. That works there
   because the top of a cutting is always the masthead and the
   headline. A photograph has no such guarantee: the subject is as
   often at the bottom of the frame as the top.
   ================================================================ */

.photogrid{columns:4 260px;column-gap:22px}
@media (max-width:1100px){ .photogrid{columns:3 240px} }
@media (max-width:820px){  .photogrid{columns:2 200px;column-gap:14px} }

/* The occasion, over the corner of the picture. Inside .galzoom so it
   travels with the image rather than sitting in the caption block,
   where six words of chip would push the caption itself below the
   fold of a short tile. */
.photo-occ{
  position:absolute;left:10px;top:10px;
  font:700 10.5px/1 Inter,system-ui,sans-serif;
  letter-spacing:.08em;text-transform:uppercase;
  padding:6px 9px;border-radius:999px;
  box-shadow:0 1px 3px rgba(15,12,28,.18)
}

.photo-tile figcaption{display:grid;gap:5px}
.photo-cap{
  font:500 13px/1.55 Inter,system-ui,sans-serif;color:var(--ink-2)
}
.photo-cap:lang(hi){font-family:"Tiro Devanagari Hindi",serif;font-size:13.5px}
/* --ink-2, not the --ink-3 the other meta lines use. This is the smallest
   text on the tile at 11px, and --ink-3 measures 3.5:1 on the card — under AA
   for text this size. It still reads as secondary against
   the caption above it through size, weight and letterspacing rather than
   through being faint. */
.photo-when{
  font:600 11px/1.4 Inter,system-ui,sans-serif;
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-2)
}
/* Only on hover or keyboard focus: 48 of these on a page is 48 lines of
   chrome, and the picture itself is already the link that matters. It stays
   in the flow — revealing it with display would reflow the whole column. */
.photo-more{
  font:600 11.5px/1.4 Inter,system-ui,sans-serif;
  color:var(--lilac-ink);text-decoration:none;
  opacity:0;transition:opacity .18s
}
.galitem:hover .photo-more,
.photo-more:focus-visible{opacity:1}
/* No hover on a touch screen, so hiding it there hides it for good — and the
   permalink is the only route from the gallery to a photograph's own page. */
@media (hover:none){ .photo-more{opacity:1} }

/* One facet, six chips: no dialog, so no filter button and no badge.
   The lit chip takes its occasion's colour through --chip-t/--chip-k,
   set inline in parts/gallery-filters.php. */
.gallery-filters{margin:22px 0 30px}
.gallery-filters .chip.is-active{
  background:var(--chip-t,var(--t-lilac));
  color:var(--chip-k,var(--lilac-ink));
  border-color:transparent
}
.gallery-count{
  margin:0 0 20px;
  font:500 13.5px/1.6 Inter,system-ui,sans-serif;color:var(--ink-2)
}
.gallery-count strong{color:var(--ink);font-weight:600}

/* ---- one photograph ---- */

.single-photo{padding:44px 0 72px}
.photo-title{
  font-family:"Fraunces",Georgia,serif;font-weight:600;
  font-size:clamp(1.5rem,1.1rem + 1.5vw,2.15rem);line-height:1.22;
  margin:10px 0 0;color:var(--ink)
}
.photo-title:lang(hi){font-family:"Tiro Devanagari Hindi",serif;line-height:1.5}
.photo-when-line{
  margin:10px 0 0;
  font:600 12px/1.4 Inter,system-ui,sans-serif;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-3)
}

/* Whole, not cropped — the frame takes the picture's own height. The tint
   behind it is what a portrait photograph sits on in a page laid out for
   prose; there is nothing to letterbox because nothing is being forced to
   a ratio. */
.photo-frame{
  margin:26px 0 0;border-radius:18px;overflow:hidden;
  border:1px solid var(--line);box-shadow:var(--sh-sm);
  background:var(--surface-2,var(--surface))
}
.photo-frame a{display:block}
.photo-frame img{display:block;width:100%;height:auto}

.photo-more-set{margin-top:52px;border-top:1px solid var(--line);padding-top:28px}
.photo-more-head{
  font-family:"Fraunces",Georgia,serif;font-weight:600;font-size:1.15rem;
  margin:0;color:var(--ink)
}
.photo-more-set .photogrid{columns:3 180px;column-gap:16px;margin-top:18px}
@media (max-width:760px){ .photo-more-set .photogrid{columns:2 140px} }

/* ---- "Beyond the desk", the homepage band ----
   The .strip shell is the ported one: same place on the page, same
   height, same caption plate. What is new is that it holds a row of
   photographs rather than one, so it reads as a way into the gallery.
   flex:1 across five, so the band is one continuous picture strip at
   any width rather than five cards with gaps. */
.photostrip{display:block;text-decoration:none;color:inherit}
.photostrip .stripshots{display:flex;height:230px}
.photostrip .stripshots img{
  flex:1 1 0;min-width:0;width:auto;max-height:none;
  object-fit:cover;object-position:center;
  transition:filter .3s
}
.photostrip:hover .stripshots img{filter:saturate(1.06) brightness(1.03)}
.photostrip:focus-visible{outline:3px solid var(--lilac);outline-offset:3px}

/* A deeper, taller scrim than the ported .cap. That one was drawn over ONE
   photograph, chosen so the caption fell on a dark part of it. Five drawn at
   random put whatever they put behind the words, so the plate has to carry the
   contrast on its own rather than borrow it from the picture. */
.photostrip .cap{
  padding-top:44px;
  background:linear-gradient(to top,
    rgba(20,12,34,.93) 0%, rgba(20,12,34,.78) 52%, rgba(20,12,34,0) 100%)
}

/* Below 700px five frames are 140px wide each and read as stripes, so
   the band drops to the first two at a usable size. */
@media (max-width:700px){
  .photostrip .stripshots{height:180px}
  .photostrip .stripshots img:nth-child(n+3){display:none}
}

/* ================================================================
   Subscribe box — the `.signup` component ported from the static build,
   which had markup but never a working form. base.css sizes the card, the
   heading, the dek and the input row; these are the states a real form has
   and a design preview did not.
   ================================================================ */

/* `.signup` is a centred column, so the enquiry form's alert — written for a
   left-aligned card — needs the same measure the input row has, or a
   one-line message spans the full width of a 1560px card. */
.signup .eform-alert{max-width:480px;margin:0 auto 20px}

/* Matches `.efield [aria-invalid="true"]`: the field that was refused is the
   one that should look refused, and inside a tinted card a border is the only
   thing that reads. */
.form input[aria-invalid="true"]{border-color:var(--coral)}

/* The honeypot's label is off-screen in an absolutely positioned box; without
   this the box is positioned against the page rather than the card, which on
   a short viewport can extend the document. */
.signup{position:relative}

/* ================================================================
   ELEVATE PROGRAM  /elevate/
   ----------------------------------------------------------------
   The page is a funnel rather than an archive: what a session is, who
   it is for, the five things it can be about, and then the form. So
   the widths narrow and widen deliberately — a reading measure at the
   top, a five-across band, three columns of areas, and the booking
   split at the bottom, which is the Invite page's `.invite-split`
   reused because it is the same two-column problem.
   ================================================================ */

/* `section{padding:76px 0 0}` in base.css is what puts every inner page's head
   clear of the ticker — the shorthand here used to reset it to 0 and the page
   started hard against the strip. Bottom only, like `.invite`. */
.elevate{padding-bottom:20px}

/* His tagline, in his capitalisation. Display type rather than a line of the
   dek: it is three claims, and setting it as prose makes it one. */
.el-tagline{
  font-family:"Fraunces",Georgia,serif;
  font-size:clamp(19px,2.1vw,26px);font-weight:600;line-height:1.4;
  letter-spacing:-.01em;color:var(--lilac-ink);
  margin:24px 0 0;max-width:30ch
}

/* The opening: head, tagline and prose in one column, the standing facts in
   the other, starting level with the kicker.

   Full wrap, so the card's right edge lines up with the offerings band, the
   area cards and the booking split below it — capped narrower, the block read
   as a different page from the one it sits on. The prose keeps a reading
   measure rather than stretching to the column, which is what leaves air
   between the two: that is a margin between columns, not a hole, because the
   card is holding the right edge.

   The card being level with the kicker is the point of the block. Under the
   header it opened below the fold, which is a poor place for the one thing a
   visitor is deciding on. */
.el-open{
  display:grid;grid-template-columns:minmax(0,1fr) 360px;
  gap:0 clamp(40px,4vw,72px)
}
.el-open-text,.el-open-side{min-width:0}
.el-lede{margin-top:32px;max-width:64ch}

.el-facts{
  background:radial-gradient(closest-side at 100% 0%,var(--t-mint),transparent 72%),var(--surface);
  border:1px solid var(--line);border-radius:22px;
  padding:26px 26px 28px;box-shadow:var(--sh-sm);
  position:sticky;top:104px
}
/* The label sits above a line of display type, so it needs to clear the line
   above it by more than the 16px the list gap gives it. */
.el-facts-list li + li{margin-top:2px}
.el-facts-list{list-style:none;margin:0 0 22px;padding:0;display:grid;gap:16px}
.el-facts-list li{display:grid;gap:3px}
.el-facts-list b{
  font-family:"Fraunces",Georgia,serif;font-size:22px;font-weight:700;
  color:var(--ink);letter-spacing:-.01em
}
/* Three platform names where the other two facts are two words, so it takes
   the size down a step rather than wrapping to three lines in a 288px card. */
.el-facts-platform{font-size:18px;line-height:1.35}
.el-facts-note{
  margin:16px 0 0;padding-top:16px;border-top:1px solid var(--line);
  font-size:12.5px;line-height:1.55;color:var(--ink-3)
}

/* `.pubs` is drawn for links to archives; these are labels, so the hover
   lift would promise a click that never comes. */
.el-offerings{margin-top:52px}
.el-offerings .names span{opacity:.85}

.el-h2{
  font-size:clamp(24px,3vw,34px);margin:64px 0 0;letter-spacing:-.02em
}
.el-h2-dek{margin:10px 0 0;color:var(--ink-2);font-size:15px;line-height:1.65;max-width:62ch}

/* ---- who I work with ---- */

.el-who{
  display:grid;grid-template-columns:repeat(5,1fr);gap:16px;margin-top:26px
}
.el-who-card{
  border-radius:18px;padding:22px 20px 24px;display:grid;gap:7px;align-content:start
}
.el-who-card b{
  font-family:"Fraunces",Georgia,serif;font-size:17px;font-weight:700;
  line-height:1.25;letter-spacing:-.01em
}
.el-who-card span{font-size:13.5px;line-height:1.55;color:var(--ink-2)}

/* ---- the five areas ---- */

/* Six columns rather than three, so five cards can fill the row they are in:
   the first three take two columns each, the last two take three each. Three
   across left the bottom-right cell empty and the section ended on a hole that
   reads as a missing sixth area. */
.el-areas{
  display:grid;grid-template-columns:repeat(6,1fr);gap:22px;margin-top:30px;
  align-items:stretch
}
.el-area{grid-column:span 2}
.el-area:nth-child(n+4){grid-column:span 3}
/* Half-width cards with seven short bullets down one side look half-empty, so
   the last two set their lists two abreast. The list is already a grid, so
   this is a column count rather than a different layout. */
.el-area:nth-child(n+4) .el-area-list{
  grid-template-columns:1fr 1fr;column-gap:26px;
  /* Down the first column then the second, not left-to-right across both —
     a list read in rows puts item 2 beside item 1 and item 5 under it. Four
     rows because every area carries seven items; a shorter list simply leaves
     the second column shorter. */
  grid-template-rows:repeat(4,auto);grid-auto-flow:column
}

/* Each card carries its own accent through --a / --a-ink / --a-tint, set
   inline from the area's palette name. One rule, five colours, and nothing
   in this stylesheet has to know how many areas there are. */
.el-area{
  display:flex;flex-direction:column;
  background:var(--surface);border:1px solid var(--line);
  border-radius:24px;padding:28px 26px 26px;box-shadow:var(--sh-sm);
  border-top:3px solid var(--a);
  transition:transform .25s cubic-bezier(.2,.8,.2,1),box-shadow .25s
}
.el-area:hover{transform:translateY(-3px);box-shadow:var(--sh-md)}

.el-area-head{display:flex;gap:16px;align-items:flex-start}
.el-area-no{
  flex:none;width:44px;height:44px;border-radius:14px;
  display:grid;place-items:center;
  background:var(--a-tint);color:var(--a-ink);
  font-family:"Fraunces",Georgia,serif;font-weight:900;font-size:17px
}
/* Both reserve their second line whether or not they need it. Cards in a row
   are the same height, but their headers were not: a one-line title beside a
   two-line one pushed that card's label and every bullet under it half a line
   down, and two lists side by side that do not start level read as a mistake.
   min-height rather than a fixed height, so a longer title still grows. */
.el-area h3{
  font-size:19px;line-height:1.3;margin:0;letter-spacing:-.01em;
  min-height:calc(2 * 1.3em)
}
.el-area-dek{
  margin:7px 0 0;font-size:13.5px;line-height:1.55;color:var(--ink-2);
  min-height:calc(2 * 1.55em)
}

.el-area-lead{
  margin:22px 0 12px;font-size:11px;font-weight:700;letter-spacing:.11em;
  text-transform:uppercase;color:var(--ink-3)
}
.el-area-list{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.el-area-list li{
  position:relative;padding-left:18px;font-size:14px;line-height:1.5;color:var(--ink)
}
.el-area-list li::before{
  content:"";position:absolute;left:0;top:.52em;
  width:7px;height:7px;border-radius:50%;background:var(--a)
}

/* margin-top:auto pins it to the bottom of whichever card it is in, so five
   lists of unequal length still end on a level row of links. */
.el-area-cta{
  margin-top:auto;padding-top:20px;
  display:inline-flex;align-items:center;gap:8px;
  font-size:13.5px;font-weight:600;color:var(--a-ink);
  text-decoration:none
}
.el-area-cta:hover{text-decoration:underline;text-underline-offset:3px}
.el-area-cta .arw{transition:transform .22s}
.el-area-cta:hover .arw{transform:translateX(3px)}

/* ---- the booking split ---- */

.el-book{scroll-margin-top:110px}
.book-card{
  background:radial-gradient(closest-side at 12% 0%,var(--t-mint),transparent 70%),var(--surface)
}

.book-tzline{
  margin:-2px 0 0;font-size:12.5px;color:var(--ink-3);
  text-transform:none;letter-spacing:0;font-weight:500
}
.book-slotfield{gap:9px}

/* ---- the calendar ----
   Hidden until booking.js decides it can draw it; the <select> underneath is
   what actually posts, and stays visible if that never happens. */
/* Two columns: the month on the left, the times for the chosen day on the
   right. One column across the whole card made each of seven cells about
   120px square — `aspect-ratio:1` in a form card that is most of a 1560px
   wrap — which is a wall calendar, not a control. Capping the month at 320px
   fixes the cell size at something a date belongs in, and the space that
   bought is where the times now live instead of pushing the form longer.

   Placed explicitly rather than by source order: the times span both of the
   left column's rows, so they start level with the month name. */
.book-cal{
  display:grid;grid-template-columns:minmax(0,320px) minmax(0,1fr);
  gap:0 26px;align-items:start;
  border:1px solid var(--line-2);border-radius:16px;
  background:var(--paper);padding:16px 18px 18px;margin-top:4px
}
.cal-head{
  grid-column:1;grid-row:1;
  display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px
}
.cal-month{
  font-family:"Fraunces",Georgia,serif;font-size:16px;font-weight:700;color:var(--ink)
}
.cal-nav{
  width:32px;height:32px;border-radius:50%;border:1px solid var(--line-2);
  background:var(--surface);color:var(--ink);cursor:pointer;font-size:17px;line-height:1;
  transition:background .18s,border-color .18s,opacity .18s
}
.cal-nav:hover:not(:disabled){border-color:var(--lilac);color:var(--lilac)}
.cal-nav:disabled{opacity:.32;cursor:default}

.cal-grid{grid-column:1;grid-row:2;display:grid;grid-template-columns:repeat(7,1fr);gap:4px}
.cal-dow{
  text-align:center;font-size:10.5px;font-weight:700;letter-spacing:.08em;
  color:var(--ink-3);padding-bottom:6px
}
.cal-day{
  position:relative;aspect-ratio:1;min-height:38px;
  display:grid;place-items:center;border-radius:11px;border:0;
  background:transparent;color:var(--ink-3);
  font-family:inherit;font-size:13.5px;font-weight:600
}
/* A date with nothing free is dimmed rather than removed: the shape of the
   month is how you find next Tuesday. */
.cal-day.is-off{opacity:.35}
button.cal-day{
  cursor:pointer;background:var(--surface);color:var(--ink);
  border:1px solid var(--line-2);
  transition:border-color .16s,background .16s,color .16s
}
button.cal-day:hover{border-color:var(--lilac);color:var(--lilac-ink)}
/* The dot is the only thing saying "this day has times" once the ink is
   already dark, so it stays visible on the chosen day too. */
button.cal-day i{
  position:absolute;bottom:5px;width:4px;height:4px;border-radius:50%;
  background:var(--mint)
}
button.cal-day.is-on{
  background:var(--lilac-ink);border-color:var(--lilac-ink);color:#FFF
}
button.cal-day.is-on i{background:rgba(255,255,255,.8)}

/* A rule down the middle rather than one across, now that the times sit
   beside the month rather than under it. */
.cal-times{
  grid-column:2;grid-row:1 / span 2;
  border-left:1px solid var(--line);padding:2px 0 0 26px;min-height:100%
}
.cal-hint{margin:0 0 12px;font-size:12.5px;color:var(--ink-3)}
/* Two abreast in the column the month left free — a single file of chips down
   a 400px column is a long scroll for eight times. */
.cal-chips{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:8px}
.cal-chip{width:100%;text-align:center}
.cal-chip{
  cursor:pointer;border:1px solid var(--line-2);background:var(--surface);
  color:var(--ink);border-radius:999px;padding:9px 15px;
  font-family:inherit;font-size:13.5px;font-weight:600;
  transition:border-color .16s,background .16s,color .16s
}
.cal-chip:hover{border-color:var(--mint);color:var(--mint-ink)}
.cal-chip.is-on{background:var(--mint-ink);border-color:var(--mint-ink);color:#FFF}

/* A live region rather than a decoration: it is the one place the chosen slot
   is written out in full, and it is what a screen reader hears when a chip is
   pressed. Empty until something is chosen, so it takes no room until then. */
/* Inside the times column, directly under the chips it is confirming — as a
   third grid row it sat level with the bottom of the month, a long way from
   the thing it was talking about. */
.cal-chosen{
  margin:16px 0 0;
  font-size:13px;font-weight:600;color:var(--mint-ink)
}
.cal-chosen:empty{display:none}

/* ---- the acknowledgement ---- */

.book-receipt{
  margin:0 0 26px;padding:22px 24px;border-radius:18px;
  background:var(--t-mint);display:grid;gap:14px
}
.book-receipt div{display:grid;gap:3px}
.book-receipt dt{
  font-size:11px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--mint-ink)
}
.book-receipt dd{margin:0;font-size:15.5px;line-height:1.5;color:var(--ink)}
.book-receipt strong{font-family:"Fraunces",Georgia,serif;font-size:19px;letter-spacing:.04em}
.book-tz{display:block;font-size:12.5px;color:var(--ink-3)}

.book-next{margin:0 0 26px;padding-left:20px;display:grid;gap:12px}
.book-next li{font-size:14.5px;line-height:1.6;color:var(--ink-2)}
.book-next strong{color:var(--ink)}
.book-next a{color:var(--lilac);text-decoration:underline;text-underline-offset:3px}

/* ---- the payment card ---- */

.book-fee{
  margin:0 0 18px;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap
}
.book-fee b{
  font-family:"Fraunces",Georgia,serif;font-size:34px;font-weight:700;
  color:var(--ink);letter-spacing:-.02em
}
.book-fee span{font-size:13px;color:var(--ink-3)}

.book-qr{
  margin:0 0 20px;padding:14px;border-radius:16px;
  background:#FFF;border:1px solid var(--line);text-align:center
}
/* White plate, always: a QR is read by a camera looking for black on white,
   and tinting the ground is how a scannable code stops scanning. */
.book-qr-img{width:100%;max-width:220px;margin:0 auto;height:auto;display:block}
.book-qr figcaption{margin-top:10px;font-size:12px;color:#5B5379}

.book-upi{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:14.5px;
  color:var(--ink);word-break:break-all
}
.book-payee{font-size:12.5px;color:var(--ink-3)}
.book-smallprint{
  margin:18px 0 0;padding-top:16px;border-top:1px solid var(--line);
  font-size:12px;line-height:1.55;color:var(--ink-3)
}

/* ---- responsive ---- */

@media (max-width:1200px){
  /* Two across, and the fifth takes the full width rather than sitting alone
     beside a gap — the same rule as above, one row narrower. */
  .el-areas{grid-template-columns:repeat(4,1fr)}
  .el-area,.el-area:nth-child(n+4){grid-column:span 2}
  .el-area:nth-child(5){grid-column:span 4}
  .el-who{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:1080px){
  .el-open{grid-template-columns:1fr;gap:32px 0}
  .el-facts{position:static}
  .el-lede{margin-top:26px}
}
@media (max-width:760px){
  .el-areas{grid-template-columns:1fr}
  .el-area,.el-area:nth-child(n+4),.el-area:nth-child(5){grid-column:auto}
  .el-area:nth-child(n+4) .el-area-list{grid-template-columns:1fr;grid-auto-flow:row}
  /* One card per row: nothing to line up with, so a one-line title should not
     hold two lines of air over its own list. */
  .el-area h3,.el-area-dek{min-height:0}
  .el-who{grid-template-columns:1fr 1fr}
  .el-tagline{max-width:none}
}
/* Under this the two columns would be about 200px each, which is narrower
   than the month can be drawn — so it goes back to one column with the times
   under a rule, which is what the border was before. */
@media (max-width:820px){
  .book-cal{grid-template-columns:1fr;padding:16px 16px 14px}
  .cal-head,.cal-grid,.cal-times{grid-column:1}
  .cal-head{grid-row:auto}
  .cal-grid{grid-row:auto;max-width:340px}
  .cal-times{
    grid-row:auto;border-left:0;border-top:1px solid var(--line);
    margin-top:16px;padding:14px 0 0
  }
}
@media (max-width:560px){
  .el-who{grid-template-columns:1fr}
  .book-cal{padding:12px 12px 12px}
  .cal-grid{max-width:none}
  .cal-day{min-height:34px;font-size:12.5px}
  .book-receipt{padding:18px 18px}
}
