/*
Theme Name: Millman
Theme URI: https://michaelmillman.com
Author: Michael Millman
Description: Editorial theme for michaelmillman.com. Classic theme, no page builder, no build step. All design decisions live in the token block below. Panels are block patterns built from core blocks.
Version: 1.0.2
Requires at least: 6.0
Requires PHP: 8.0
License: Proprietary
Text Domain: millman
*/

/* ============================================================
   TOKENS — THE SINGLE SOURCE OF TRUTH.

   Every size, colour, spacing and tracking value on this site
   is set here and nowhere else. Change a value here and it
   changes everywhere it is used.

   RULE FOR ANY MODEL OR PERSON EDITING THIS THEME:
   never hardcode a colour, size, tracking or spacing value in
   a template, a pattern, or a block. Use a token. If a value
   you need does not exist as a token, add it here first.
   ============================================================ */
:root{
  /* ---- Colour ---- */
  --paper:        #EEE9DF;   /* primary ground */
  --paper-deep:   #E4DED1;   /* alternate band */
  --ink:          #191512;   /* warm near-black. never pure black. */
  --ink-soft:     #5C544C;   /* body text on paper */
  --ink-muted:    #8A8076;   /* captions, meta */
  --oxblood:      #6E2639;   /* accent. rare. means something. */
  --hairline:     #D8D1C4;   /* rules on paper */
  --hairline-dk:  #3A322B;   /* rules on ink */
  --paper-on-ink: #F3EFE7;   /* type on dark grounds */
  --paper-dim:    #A79C90;   /* secondary type on dark grounds */
  --paper-quiet:  #8A7F73;   /* tertiary type on dark grounds */
  --paper-bright: #C4B9AC;   /* attribution on dark grounds */

  /* ---- Families ---- */
  --display: "Playfair Display", Georgia, serif;
  --sans:    "Archivo", Helvetica, Arial, sans-serif;

  /* ---- Type scale ---- */
  --t-mega:    clamp(3.4rem, 13vw, 13rem);
  --t-hero:    clamp(2.1rem, 7.6vw, 7.6rem);
  --t-mark:    clamp(1.6rem, 4.2vw, 3.4rem);
  --t-heroq:   clamp(1rem, 2.15vw, 1.85rem);
  --t-display: clamp(2.2rem, 4.8vw, 4.2rem);
  --t-quote:   clamp(1.55rem, 3.1vw, 2.75rem);
  --t-stack:   clamp(1.9rem, 4.3vw, 3.7rem);
  --t-figure:  clamp(3.2rem, 8.5vw, 7.5rem);
  --t-foot:    clamp(2rem, 6.5vw, 5rem);
  --t-lede:    clamp(1.05rem, 1.5vw, 1.35rem);
  --t-body:    1rem;
  --t-small:   0.875rem;
  --t-eyebrow: 0.6875rem;
  --t-attr:    clamp(.7rem, .92vw, .84rem);

  /* ---- Tracking scale. Runs inverse to size. ---- */
  --tr-mega:    -0.080em;
  --tr-hero:    -0.080em;
  --tr-display: -0.060em;
  --tr-quote:   -0.050em;
  --tr-stack:   -0.060em;
  --tr-mid:     -0.040em;
  --tr-italic:  -0.040em;
  --tr-eyebrow:  0.400em;
  --tr-attr:     0.200em;
  --tr-body:    -0.002em;

  /* The wordmark is hand-kerned. It does NOT inherit --tr-hero.
     Its un-nudged letters rely on this value. Do not change it. */
  --tr-wordmark: -0.020em;

  /* ---- Italic drop-in optical spacing. Asymmetric on purpose.
     The air goes AFTER the italic, not before. ---- */
  --di-lead:  0.015em;
  --di-trail: 0.100em;

  /* ---- Spacing ---- */
  --gutter:     clamp(1.5rem, 6vw, 7rem);
  --band:       clamp(5rem, 13vh, 11rem);
  --band-tight: clamp(3rem, 7vh, 6rem);
  --measure:    38rem;

  /* ---- Motion ---- */
  --reveal-dur:  1100ms;
  --reveal-ease: cubic-bezier(.16,.72,.24,1);

  /* ---- Hero image. Swap the file at assets/img/hero.jpg to
     change the portrait, or override this in the pattern. ---- */
  --hero-focus: 72% center;
  /* Sampled from the portrait's own left edge so the panel ground and
     the photograph meet with no visible seam. */
  --hero-ground: #070707;
}

/* ============================================================
   RESET AND BASE
   ============================================================ */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
body{
  margin:0;background:var(--paper);color:var(--ink-soft);
  font-family:var(--sans);font-size:var(--t-body);font-weight:300;
  line-height:1.75;letter-spacing:var(--tr-body);
}
img{display:block;max-width:100%;height:auto}
a{color:inherit}

/* ============================================================
   PRIMITIVES
   ============================================================ */
.eyebrow{
  font-family:var(--sans);font-size:var(--t-eyebrow);font-weight:500;
  letter-spacing:var(--tr-eyebrow);text-transform:uppercase;
  color:var(--ink-muted);margin:0 0 1.6rem;
}
.eyebrow--ruled{padding-bottom:.9rem;border-bottom:1px solid var(--hairline)}
.on-ink .eyebrow{color:var(--paper-quiet)}
.on-ink .eyebrow--ruled{border-color:var(--hairline-dk)}

.display{
  font-family:var(--display);font-weight:400;
  line-height:1.06;letter-spacing:var(--tr-display);
  color:var(--ink);margin:0;font-kerning:normal;
}
.on-ink .display{color:var(--paper-on-ink)}
.display--section{font-size:var(--t-display)}

.lede{font-size:var(--t-lede);line-height:1.65;max-width:var(--measure);font-weight:300}
.body{max-width:var(--measure)}
.body p{margin:0 0 1.3em}
.on-ink{background:var(--ink);color:var(--paper-dim)}

/* ============================================================
   THE ITALIC DROP-IN. One class. Does most of the work.
   Optical correction: a symmetrical gap around an italic reads
   lopsided. The air goes after the italic, not before.
   ============================================================ */
.di{
  font-style:italic;font-weight:400;
  letter-spacing:var(--tr-italic);
  margin-left:var(--di-lead);
  margin-right:var(--di-trail);
}

/* ============================================================
   THE WORDMARK — kerned by hand. Do not re-space.
   ============================================================ */
.wordmark{
  font-family:var(--display);font-weight:400;
  font-size:var(--t-hero);line-height:1.05;
  letter-spacing:var(--tr-wordmark);
  white-space:nowrap;font-kerning:normal;margin:0;
  color:var(--paper-on-ink);
}
.wordmark span{display:inline-block}

/* ============================================================
   PANEL 01 — HERO
   Full-bleed monochrome portrait. Subject right, type left in
   the dark third. Never a scrim: the photograph is lit for it.
   ============================================================ */
/* The hero is one composition that scales as a unit, not a layout that
   reflows. The panel takes the portrait's own aspect ratio and every
   size inside it is expressed in vw, so the photograph and the type
   hold their exact relationship at any window width. Same behaviour as
   a printed page reduced on a photocopier. */
.hero{
  position:relative;
  aspect-ratio:1672 / 941;
  width:100%;
  display:flex;align-items:center;
  background:var(--hero-ground);overflow:hidden;
}
.hero__media{
  position:absolute;inset:0;
  background-image:var(--hero-img);
  background-size:cover;
  background-position:center;
  background-repeat:no-repeat;
}
.hero__inner{position:relative;width:100%;padding:0 6vw}

/* Type sizes in vw. These are the values that produced the composition
   at 1920 wide, expressed proportionally so they hold everywhere. */
.hero .wordmark{font-size:6.3vw;line-height:1.05}
.hero__mark{
  font-family:var(--display);font-style:italic;font-weight:400;
  font-size:2.83vw;color:var(--paper-on-ink);
  margin:.5vw 0 0;opacity:.94;letter-spacing:var(--tr-italic);
}
/* The attribution block shrink-wraps to the quote, so the rule measures
   exactly the width of the line it introduces. Structural, not
   decorative: it belongs to the quote. */
.hero__credit{display:inline-block;margin:2.3vw 0 0}
.hero__rule{width:100%;height:1px;background:#6E655B;margin:0 0 1.2vw}
.hero__quote{
  font-family:var(--display);font-style:italic;font-weight:400;
  font-size:1.54vw;line-height:1.4;letter-spacing:var(--tr-italic);
  color:var(--paper-on-ink);white-space:nowrap;margin:0;
}
.hero__attr{
  font-family:var(--sans);font-size:.7vw;font-weight:500;
  letter-spacing:var(--tr-attr);text-transform:uppercase;
  color:var(--paper-bright);margin:1.1vw 0 0;
}

/* Phone: same overlaid composition as desktop, re-proportioned. The
   portrait fills the panel height and is pushed hard past the right
   edge so his left arm crops off entirely, leaving the left of the
   frame clear for the type. */
@media(max-width:700px){
  /* Tuned by Michael in the browser at 414px wide, 2026-08-17.
     His pixel values converted to vw so the composition holds at every
     phone width rather than only at 414. */
  .hero{aspect-ratio:69 / 50;align-items:center}
  .hero__media{
    top:0;bottom:auto;height:72.46vw;
    background-size:auto 100%;
    background-position:right -18vw center;
  }
  .hero__media::after{
    content:"";position:absolute;inset:0;
    background:linear-gradient(90deg,
      var(--hero-ground) 0%, rgba(7,7,7,.66) 22%, rgba(7,7,7,0) 50%);
  }
  .hero__inner{padding:0 7vw 0 3.62vw;margin-top:5.8vw}
  .hero__inner>*{max-width:70%}

  /* Wordmark down, everything under it up. The rule takes its length
     from the quote, so a larger quote lengthens the rule with it. */
  .hero .wordmark{font-size:8.4vw;line-height:1.05}
  .hero__mark{font-size:4.9vw;margin:1.8vw 0 0}
  .hero__credit{margin:5.4vw 0 0;max-width:none}
  .hero__rule{margin:0 0 2.8vw}
  .hero__quote{font-size:2.95vw;white-space:nowrap}
  .hero__attr{font-size:2vw;margin:2.6vw 0 0}
}

/* ============================================================
   PANEL 02 — CROPPED MEGA STATEMENT  ·  SIGNATURE
   Type too large for the frame. The reader's own mind closes
   the word. The method, performed by the page.
   ============================================================ */
.mega{padding:var(--band) 0;overflow:hidden;text-align:center}
.mega__word{
  font-family:var(--display);font-weight:400;font-size:var(--t-mega);
  line-height:.9;letter-spacing:var(--tr-mega);color:var(--ink);
  white-space:nowrap;margin:0;font-kerning:normal;
}
.mega__word .di{--di-lead:0.02em;--di-trail:0.14em}
.mega__sub{
  font-family:var(--sans);font-size:var(--t-eyebrow);font-weight:500;
  letter-spacing:var(--tr-eyebrow);text-transform:uppercase;
  color:var(--ink-muted);margin:2.4rem 0 0;
}
.mega--ink{background:var(--ink)}
.mega--ink .mega__word{color:var(--paper-on-ink)}
.mega--ink .mega__sub{color:var(--paper-quiet)}

/* ============================================================
   PANEL 03 — QUOTE ON OPEN GROUND
   ============================================================ */
.quote{padding:var(--band) var(--gutter);background:var(--paper-deep)}
.quote__inner{max-width:52rem;margin:0 auto;text-align:center}
.quote__text{
  font-family:var(--display);font-weight:400;font-size:var(--t-quote);
  line-height:1.34;color:var(--ink);margin:0;letter-spacing:var(--tr-quote);
}
.quote__attr{
  font-family:var(--sans);font-size:var(--t-eyebrow);font-weight:500;
  letter-spacing:var(--tr-eyebrow);text-transform:uppercase;
  color:var(--ink-muted);margin:2.6rem 0 0;
}

/* Dark variant. Runs continuous with the hero above it so the opening
   claim reads as still being spoken by the man in the photograph,
   rather than as the site starting over on paper. */
.quote--ink{background:var(--hero-ground)}
.quote--ink .quote__text{color:var(--paper-on-ink)}
.quote--ink .quote__attr{color:var(--paper-bright)}

/* The challenge panel. Wider measure than a pull quote, because the
   claim is a sentence rather than a fragment, and a rule above the
   attribution to separate the assertion from the man making it. */
.quote--claim .quote__inner{max-width:58rem}
.quote--claim .quote__text{font-size:clamp(1.35rem,2.6vw,2.3rem);line-height:1.42}
.quote--claim .quote__attr{
  font-family:var(--display);font-style:italic;font-weight:400;
  font-size:clamp(.95rem,1.25vw,1.15rem);
  letter-spacing:var(--tr-italic);text-transform:none;
  margin:2.2rem 0 0;
}
@media(max-width:700px){
  .quote--claim .quote__text{font-size:5.2vw;line-height:1.4}
  .quote--claim .quote__attr{font-size:3.4vw;margin:6vw 0 0}
}

/* ============================================================
   PANEL 04 — IDENTITY STACK
   Alternating roman and italic. Presents someone who is
   several things at once without arguing for it.
   ============================================================ */
.stack{padding:var(--band) var(--gutter)}
.stack__inner{max-width:64rem;margin:0 auto}
.stack__list{
  font-family:var(--display);font-weight:400;font-size:var(--t-stack);
  line-height:1.2;color:var(--ink);margin:0;letter-spacing:var(--tr-stack);
}
.stack__list span{display:block}
.stack__note{margin:3rem 0 0;max-width:30rem;font-size:var(--t-small);color:var(--ink-muted)}

/* ============================================================
   PANEL 05 — ASYMMETRIC SPLIT. Never centred.
   ============================================================ */
.split{display:grid;grid-template-columns:1fr;align-items:center}
.split__media{position:relative;min-height:60vh;background:var(--ink);background-size:cover;background-position:center}
.split__text{padding:var(--band) var(--gutter)}
@media(min-width:900px){
  .split{grid-template-columns:1.15fr 1fr}
  .split--flip .split__media{order:2}
  .split__media{min-height:88vh}
}

/* ============================================================
   PANEL 06 — HAIRLINE STATEMENT COLUMN
   ============================================================ */
.stmt{padding:var(--band) var(--gutter);display:grid;grid-template-columns:1fr;gap:3rem}
@media(min-width:900px){.stmt{grid-template-columns:1fr 1.35fr;gap:clamp(3rem,7vw,8rem)}}
.stmt__list{margin:0;padding:0;list-style:none}
.stmt__list li{
  padding:1.5rem 0;border-top:1px solid var(--hairline);
  font-size:var(--t-lede);line-height:1.55;color:var(--ink-soft);
}
.stmt__list li:last-child{border-bottom:1px solid var(--hairline)}

/* ============================================================
   PANEL 07 — PROOF ROW. The names are the proof.
   ============================================================ */
.proof{padding:var(--band) var(--gutter);background:var(--paper-deep)}
.proof__head{text-align:center;margin:0 auto 4.5rem;max-width:44rem}
.proof__grid{display:grid;grid-template-columns:repeat(2,1fr);gap:clamp(2rem,4vw,3.5rem);max-width:74rem;margin:0 auto}
@media(min-width:760px){.proof__grid{grid-template-columns:repeat(3,1fr)}}
.proof__item{padding-top:1.4rem;border-top:1px solid var(--hairline)}
.proof__name{
  font-family:var(--display);font-weight:400;font-size:clamp(1.15rem,1.9vw,1.6rem);
  color:var(--ink);margin:0 0 .5rem;letter-spacing:var(--tr-mid);
}
.proof__role{font-size:var(--t-small);color:var(--ink-muted);margin:0;line-height:1.5}

/* ============================================================
   PANEL 08 — FIGURE. The only place oxblood appears.
   ============================================================ */
.figure{padding:var(--band) var(--gutter);text-align:center}
.figure__num{
  font-family:var(--display);font-weight:400;font-size:var(--t-figure);
  line-height:1;letter-spacing:var(--tr-mega);color:var(--oxblood);margin:0;
}
.figure__cap{max-width:30rem;margin:2rem auto 0;font-size:var(--t-small);color:var(--ink-muted)}

/* ============================================================
   ARTICLE — long-form pages and blog posts
   ============================================================ */
.article{padding:var(--band) var(--gutter)}
.article__inner{max-width:var(--measure);margin:0 auto}
.article__title{
  font-family:var(--display);font-weight:400;font-size:var(--t-display);
  line-height:1.06;letter-spacing:var(--tr-display);color:var(--ink);margin:0 0 2.5rem;
}
.article__meta{font-size:var(--t-eyebrow);font-weight:500;letter-spacing:var(--tr-eyebrow);
  text-transform:uppercase;color:var(--ink-muted);margin:0 0 1.2rem}
.article__body p{margin:0 0 1.4em}
.article__body h2{
  font-family:var(--display);font-weight:400;font-size:clamp(1.6rem,2.6vw,2.2rem);
  letter-spacing:var(--tr-quote);color:var(--ink);margin:2.6em 0 .7em;line-height:1.2;
}
.article__body h3{
  font-family:var(--display);font-weight:400;font-size:clamp(1.25rem,1.8vw,1.5rem);
  letter-spacing:var(--tr-mid);color:var(--ink);margin:2.2em 0 .6em;
}
.article__body blockquote{
  margin:2.4em 0;padding:0 0 0 1.6rem;border-left:1px solid var(--hairline);
  font-family:var(--display);font-style:italic;font-size:var(--t-lede);color:var(--ink);
}
.article__body a{color:var(--oxblood);text-decoration:underline;text-underline-offset:.18em}
.article__body img{margin:2.4em 0}

/* ============================================================
   HEADER / NAV
   ============================================================ */
.site-head{
  position:absolute;top:0;left:0;right:0;z-index:10;
  padding:1.6rem var(--gutter);display:flex;justify-content:space-between;align-items:center;
}
.site-head--solid{position:relative;background:var(--ink)}
.site-head__mark{
  font-family:var(--display);font-size:1.05rem;letter-spacing:var(--tr-mid);
  color:var(--paper-on-ink);text-decoration:none;
}
.nav ul{list-style:none;margin:0;padding:0;display:flex;gap:clamp(1rem,2.2vw,2.4rem);flex-wrap:wrap}
.nav a{
  font-family:var(--sans);font-size:var(--t-eyebrow);font-weight:500;
  letter-spacing:var(--tr-attr);text-transform:uppercase;
  color:var(--paper-dim);text-decoration:none;
}
.nav a:hover{color:var(--paper-on-ink)}
.nav a:focus-visible{outline:1px solid var(--paper-on-ink);outline-offset:4px}
@media(max-width:759px){.nav{display:none}}

/* ============================================================
   FOOTER
   ============================================================ */
.foot{background:var(--ink);padding:var(--band-tight) var(--gutter) 3rem}
.foot__inner{max-width:74rem;margin:0 auto}
.foot__word{
  font-family:var(--display);font-weight:400;font-size:var(--t-foot);
  line-height:1.05;letter-spacing:var(--tr-display);color:var(--paper-on-ink);margin:0 0 3.5rem;
}
.foot__cols{display:grid;grid-template-columns:1fr;gap:2.5rem;padding-top:2.5rem;border-top:1px solid var(--hairline-dk)}
@media(min-width:760px){.foot__cols{grid-template-columns:repeat(3,1fr)}}
.foot__cols ul{list-style:none;margin:0;padding:0}
.foot a{color:var(--paper-dim);text-decoration:none;display:block;padding:.35rem 0;font-size:var(--t-small)}
.foot a:hover{color:var(--paper-on-ink)}
.foot a:focus-visible{outline:1px solid var(--paper-on-ink);outline-offset:3px}
.foot__fine{margin:3.5rem 0 0;font-size:.75rem;color:#6E655B}

/* ============================================================
   MOTION — arrives once, slowly, whole panel at a time.
   ============================================================ */
.rv{opacity:0;transform:translateY(26px);
    transition:opacity var(--reveal-dur) var(--reveal-ease),transform var(--reveal-dur) var(--reveal-ease)}
.rv.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.rv{opacity:1;transform:none;transition:none}}

/* ============================================================
   ACCESSIBILITY
   ============================================================ */
.skip-link{
  position:absolute;left:-9999px;top:0;z-index:100;
  background:var(--paper);color:var(--ink);padding:.9rem 1.4rem;
  font-size:var(--t-small);
}
.skip-link:focus{left:0}
.screen-reader-text{
  border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;
  padding:0;position:absolute;width:1px;word-wrap:normal;
}

/* ============================================================
   PER-INSTANCE DROP-IN OVERRIDES.

   What decides the spacing is the shape on each side of the
   italic, not the italic itself.

   NEEDS AIR: a descender or ascender leaning the same way as
   the italic nests into it (y + g, l + f).
   NEEDS LESS: two closed round shapes together already read
   open (s + s, e + o). Extra space becomes a hole.

   Suffix L is the lead, T is the trail. Written as .di.di--XX
   and placed LAST so they outrank the per-panel rules, which
   are two-part selectors and would otherwise win.
   ============================================================ */
.di.di--L0{--di-lead:0}
.di.di--L1{--di-lead:0.05em}
.di.di--L2{--di-lead:0.10em}
.di.di--L3{--di-lead:0.16em}
.di.di--L4{--di-lead:0.24em}
.di.di--L5{--di-lead:0.34em}
.di.di--T0{--di-trail:0}
.di.di--T1{--di-trail:0.05em}
.di.di--T2{--di-trail:0.10em}
.di.di--T3{--di-trail:0.16em}
.di.di--T4{--di-trail:0.24em}
.di.di--T5{--di-trail:0.34em}
