:root {
    /* Paper, ink, two greys and one muted accent. Nothing metallic.
       Measured on paper: ink 16.0:1, grey 4.75:1, brick 6.72:1, and his
       navy suit separates at 15:1 (the petrol ground managed 2.15:1). */
    --paper: #f2f1ed;
    --ink:   #14161a;
    --body:  #45494e;
    --grey:  #5f6267;
    --line:  #d5d4cf;
    --rule:  #b9b8b2;
    --brick: #8c3a32;

    --sans: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { color-scheme: light; -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; }}
body { background: var(--paper); color: var(--ink); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
img { display: block; max-width: 100%; height: auto; }
picture { display: contents; }
a { color: inherit; text-decoration: none; }
.skip-link { position: absolute; left: -9999px; top: 0; z-index: 90; background: var(--ink); color: var(--paper); padding: 12px 20px; font-size: 14px; }
.skip-link:focus { left: 0; }

/* ── One grid for the whole page. Things are placed on it deliberately,
   which is the point: nothing simply stacks flush left. ───────────── */
.wrap { max-width: 1400px; margin: 0 auto; padding: 0 clamp(22px, 4vw, 64px); width: 100%; }
.grid {
    display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: clamp(14px, 1.8vw, 26px);
    row-gap: clamp(22px, 2.8vw, 40px);
}

/* ── Header ───────────────────────────────────────────────────────── */

/* ── Hero: figure on paper, no band, no overlay, nothing behind it ── */
/* ── The backdrop plate ───────────────────────────────────────────────
   A defocused glass-walled meeting room, washed heavily towards the paper
   so the dark type on it stays legible and it reads as a tinted band with
   depth rather than a photograph competing with the words. The figure in
   front stays a separate transparent element. */
.hero { position: relative; overflow: hidden; }
.backdrop { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
/* out of flow: height:100% has no definite parent height to resolve
   against in normal flow, and reverts to the image's own aspect ratio */
.backdrop img { position: absolute; inset: 0; width: 100%; height: 100%;
                object-fit: cover; object-position: 50% 52%; display: block;
                opacity: .92; }
.hero::before {
    content: ''; position: absolute; inset: 0; z-index: 1;
    background:
      /* The plate comes forward: 92% opacity with the wash clearing away to
         the right, so the glass-walled room is a real backdrop rather than a
         faint texture. Heavy on the left, where the copy sits. */
      linear-gradient(93deg,
        rgba(236,237,238,.97) 0%,  rgba(236,237,238,.93) 34%,
        rgba(236,237,238,.62) 56%, rgba(236,237,238,.22) 78%,
        rgba(236,237,238,.08) 100%);
}
/* Same as the other two: stacked, the copy sits over the lit half. At 390
   the role line measured 3.83:1 against it, under the 4.5 it needs. */
@media (max-width: 900px) {
    .hero::before {
        background: linear-gradient(180deg,
            rgba(236,237,238,.95) 0%, rgba(236,237,238,.92) 58%,
            rgba(236,237,238,.82) 82%, rgba(236,237,238,.70) 100%);
    }
}
.hero .wrap, .hero .lead, .hero .figure { position: relative; z-index: 2; }
.hero .grid { align-items: end; }
.lead { grid-column: 1 / 8; padding-block: clamp(40px, 6vw, 96px) clamp(36px, 5vw, 76px); position: relative; z-index: 2; }
.lead h1 {
    font-size: clamp(36px, 5.2vw, 74px); font-weight: 500;
    line-height: 1.04; letter-spacing: -.032em; max-width: 26ch;
}
.lead .role { margin-top: clamp(16px, 1.8vw, 22px); font-size: clamp(16px, 1.5vw, 19px); font-weight: 400; line-height: 1.4; color: var(--grey); max-width: 40ch; }
.lead .intro { margin-top: clamp(22px, 2.6vw, 34px); font-size: clamp(16px, 1.45vw, 17.5px); line-height: 1.7; color: var(--body); max-width: 58ch; }

.figure img { width: 100%; }

/* ── Body ─────────────────────────────────────────────────────────── */
main { border-top: 1px solid var(--rule); }
.band { padding-block: clamp(46px, 7vw, 118px); }

/* the opening statement is indented off the left edge on purpose */
.statement { grid-column: 4 / 12; font-size: clamp(22px, 2.7vw, 37px); font-weight: 400; line-height: 1.28; letter-spacing: -.02em; }

/* a narrow left rail against a wide text column */
.rail { grid-column: 1 / 3; }
.rail h2 { font-size: 14px; font-weight: 600; color: var(--grey); line-height: 1.4; }
.rail ul { list-style: none; margin-top: 14px; }
.rail li { font-size: clamp(15px, 1.35vw, 17px); font-weight: 500; padding-block: 7px; border-bottom: 1px solid var(--line); }
.rail li:last-child { border-bottom: 0; }

.headline { grid-column: 4 / 11; font-size: clamp(24px, 2.7vw, 36px); font-weight: 600; line-height: 1.14; letter-spacing: -.026em; }
/* the lead passage gets more room and larger type than the three notes,
   because it is doing more work than they are */
.principal { grid-column: 4 / 10; margin-top: clamp(18px, 2vw, 26px); }
.principal p { font-size: clamp(17px, 1.6vw, 19.5px); line-height: 1.66; color: var(--body); }
.principal p + p { margin-top: .85em; }

/* his words, as type on paper, indented again */

footer { border-top: 1px solid var(--rule); }
footer .grid { padding-block: clamp(22px, 2.6vw, 32px) clamp(30px, 4vw, 52px); align-items: center; }
footer .copy { grid-column: 1 / 7; font-size: 14px; color: var(--grey); }
footer ul { grid-column: 10 / 13; list-style: none; display: flex; justify-content: flex-end; gap: 20px; font-size: 14px; }
footer ul a { display: inline-block; padding-block: 12px; color: var(--grey); }
footer ul a:hover { color: var(--ink); }

.to-top {
    position: fixed; right: clamp(16px, 2.4vw, 30px); bottom: clamp(16px, 2.4vw, 30px);
    width: 44px; height: 44px; border-radius: 0; border: 1px solid var(--rule);
    background: var(--paper); color: var(--ink); cursor: pointer;
    display: grid; place-items: center; z-index: 80;
    opacity: 0; visibility: hidden;
    transition: opacity .2s ease, visibility .2s;
}
.to-top.show { opacity: 1; visibility: visible; }
.to-top:hover { border-color: var(--ink); }
@media (prefers-reduced-motion: reduce) { .to-top { transition: none; }}

@media (max-width: 1100px) {
    .statement { grid-column: 3 / 13; }
    .headline { grid-column: 4 / 13; }
    .principal { grid-column: 4 / 11; }}
@media (max-width: 900px) {
    /* the grid folds to a single column, but the indents survive as a
       smaller inset so the page keeps its structure */
.lead { grid-column: 1 / 13; }
    .rail { grid-column: 1 / 13; margin-bottom: 20px; }
    .statement, .headline, .principal { grid-column: 1 / 13; }
    .principal { margin-top: 20px; }
    footer .copy { grid-column: 1 / 13; }
    footer ul { grid-column: 1 / 13; justify-content: flex-start; margin-top: 4px; }
    .rail ul { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 clamp(14px, 2vw, 26px); }
    .rail li { border-bottom: 0; border-top: 1px solid var(--line); }}
@media (max-width: 620px) {
    .rail ul { grid-template-columns: minmax(0, 1fr); }
    .rail li { border-top: 1px solid var(--line); }}

/* ── Motion ───────────────────────────────────────────────────────────
   All of it is gated behind .js-anim, which motion.js adds, so with JS off
   the page renders complete and static. Travel is deliberately short: this
   is a restrained layout and motion that announces itself would fight it. */
.js-anim .anim-reveal, .js-anim .anim-stagger > * {
    opacity: 0; transform: translateY(14px);
    transition: opacity .55s cubic-bezier(.22,.61,.36,1),
                transform .55s cubic-bezier(.22,.61,.36,1);
}
.js-anim .anim-stagger > * { transition-delay: calc(var(--anim-i, 0) * .06s); }
.js-anim .anim-reveal.in-view, .js-anim .anim-stagger.in-view > * { opacity: 1; transform: none; }

/* the name arrives a word at a time rather than simply being there */
.js-anim [data-anim-words] .word {
    display: inline-block;
    opacity: 0; transform: translateY(.28em);
    transition: opacity .5s cubic-bezier(.22,.61,.36,1),
                transform .6s cubic-bezier(.22,.61,.36,1);
    transition-delay: calc(var(--word-i, 0) * .07s + .05s);
}
.js-anim [data-anim-words].in-view .word { opacity: 1; transform: none; }


@media (prefers-reduced-motion: reduce) {
    .js-anim .anim-reveal, .js-anim .anim-stagger > *, .js-anim [data-anim-words] .word {
        opacity: 1; transform: none; transition: none;
    }
}

/* ── Interior pages ───────────────────────────────────────────────────
   The homepage has a figure in its header; interior pages have a heading
   and a standfirst, set on the same grid and indented the same way so the
   pages read as one site. */
.page-head { border-bottom: 1px solid var(--rule); }
.page-head .grid { padding-block: clamp(34px, 5vw, 76px) clamp(28px, 4vw, 54px); }
.page-head h1 {
    grid-column: 1 / 9;
    font-size: clamp(32px, 4.4vw, 60px); font-weight: 500;
    line-height: 1.06; letter-spacing: -.03em;
}
.page-head .lede {
    grid-column: 1 / 8; margin-top: clamp(16px, 2vw, 24px);
    font-size: clamp(17px, 1.7vw, 21px); font-weight: 400; line-height: 1.5;
    letter-spacing: -.012em; color: var(--body);
}

/* one onward link at the foot of a page, not a grid of cards */
.onward { grid-column: 4 / 11; margin-top: clamp(28px, 3.4vw, 46px); }
.onward a {
    font-size: clamp(16px, 1.5vw, 18px); font-weight: 600; color: var(--brick);
    padding-bottom: 6px; border-bottom: 1px solid var(--brick);
}

/* ── Footer, now carrying legal links as a real site does ─────────── */
footer .legal { grid-column: 7 / 13; list-style: none; display: flex; justify-content: flex-end; gap: 20px; font-size: 14px; }
footer .legal a { display: inline-block; padding-block: 12px; color: var(--grey); }
footer .legal a:hover { color: var(--ink); }

@media (max-width: 900px) {
    .page-head h1, .page-head .lede { grid-column: 1 / 13; }
    .onward { grid-column: 1 / 13; }
    footer .legal { grid-column: 1 / 13; justify-content: flex-start; }}

/* ── org identity ─────────────────────────────────────────────────────
   Cool grey paper with an ink-blue accent. The three domains each get one
   ground: .com is warm dark, .net carries a muted sage band, and this one
   is the cool institutional end of the set. Measured on this paper: ink
   15.5:1, grey 5.41:1, accent 7.86:1, and his navy suit separates at
   14.4:1 (every dark ground merged it at under 2.3:1). ──────────────── */
:root {
    --paper: #ecedee;
    --ink: #131619;
    --body: #42464a;
    --grey: #5c6064;
    --line: #d2d5d8;
    --rule: #b4b8bc;
    --brick: #2f4a63;
}

/* Both hero items are pinned to row 1. Without that, sparse auto-placement
   puts the figure in row 1 and pushes the name to row 2, and the cut-out
   ends up floating in a band of its own with paper under it -- which reads
   as a cropped photograph rather than a figure. Aligned to the end of the
   row it stands on the rule that opens <main>, which is the whole point of
   a cut-out on paper. */
.hero .grid { align-items: end; }
.figure {
    grid-column: 9 / 13; grid-row: 1; margin: 0; align-self: end;
    display: flex; align-items: flex-end;
}
.figure img { width: 100%; display: block; }
.lead { grid-column: 1 / 8; grid-row: 1; }
@media (max-width: 900px) {
    /* Stacked, but the copy comes first and the figure keeps the right edge
       below it, so it still stands on the rule that opens <main> instead of
       floating between the header and the name. */
    .lead { grid-column: 1 / 13; grid-row: 1; padding-bottom: 0; }
    .figure { grid-column: 6 / 13; grid-row: 2; }}


/* the top bar carries the domain's subject on the right, where .com has nav */

/* the hero's own copy, mirroring .com's lead but without a call to action */
.lead { padding-block: clamp(40px, 6vw, 96px) clamp(36px, 5vw, 76px); position: relative; z-index: 2; }
/* Sized to hold his name on one line on desktop. The 15ch cap was what
   forced the break; measured, the name needs 696px in a 739px column at
   1440, so it fits at this size once the cap is lifted. */
.lead h1 { font-size: clamp(32px, 4.5vw, 64px); font-weight: 500; line-height: 1.04; letter-spacing: -.032em; max-width: 26ch; }
.lead .role { margin-top: clamp(14px, 1.7vw, 20px); font-size: clamp(15px, 1.4vw, 18px); font-weight: 400; line-height: 1.4; color: var(--grey); }
.lead .intro { margin-top: clamp(20px, 2.4vw, 30px); font-size: clamp(16px, 1.45vw, 17.5px); line-height: 1.7; color: var(--body); max-width: 58ch; }

/* the areas rail gets its own band under the hero rather than a strip */
.rail-band { padding-block: clamp(26px, 3.4vw, 46px); border-top: 1px solid var(--rule); }
.rail-band .rail { grid-column: 1 / 13; }
.rail-band .rail h2 { font-size: 14px; font-weight: 600; color: var(--grey); margin-bottom: 14px; }
.rail-band .rail ul { list-style: none; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0 clamp(14px, 1.8vw, 26px); }
.rail-band .rail li { font-size: clamp(15px, 1.5vw, 19px); font-weight: 500; letter-spacing: -.018em; padding-block: 11px; border-top: 1px solid var(--ink); }

@media (max-width: 900px) {
    .rail-band .rail ul { grid-template-columns: repeat(2, minmax(0, 1fr)); }}
@media (max-width: 560px) {
    .rail-band .rail ul { grid-template-columns: minmax(0, 1fr); }}
.entries { grid-column: 1 / 13; }
.entry-row {
    display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: clamp(14px, 1.8vw, 26px);
    padding-block: clamp(24px, 3vw, 40px);
    border-top: 1px solid var(--line);
}
.entry-row:first-child { border-top: 1px solid var(--ink); }
.entry-row .when {
    grid-column: 1 / 3; font-size: 14px; font-weight: 600; color: var(--grey);
    line-height: 1.4;
}
.entry-row h3 {
    grid-column: 4 / 8;
    font-size: clamp(19px, 2vw, 26px); font-weight: 500;
    line-height: 1.18; letter-spacing: -.024em;
}
.entry-row p {
    grid-column: 8 / 13; font-size: 16px; line-height: 1.68; color: var(--body);
}

.numbered { grid-column: 1 / 13; }
.num-row {
    display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
    column-gap: clamp(14px, 1.8vw, 26px);
    padding-block: clamp(22px, 2.8vw, 38px);
    border-top: 1px solid var(--line);
}
.num-row:first-child { border-top: 1px solid var(--ink); }
.num-row .n { grid-column: 1 / 2; font-size: 14px; font-weight: 600; color: var(--grey); }
.num-row h3 {
    grid-column: 2 / 7;
    font-size: clamp(17px, 1.75vw, 22px); font-weight: 500;
    line-height: 1.2; letter-spacing: -.022em;
}
.num-row p {
    grid-column: 7 / 13; font-size: 16px; line-height: 1.68; color: var(--body);
}

@media (max-width: 1100px) {    .entry-row h3 { grid-column: 3 / 8; }
    .entry-row p { grid-column: 8 / 13; }
    .num-row h3 { grid-column: 2 / 6; }
    .num-row p { grid-column: 6 / 13; }}
@media (max-width: 900px) {    .entry-row .when, .entry-row h3, .entry-row p, .num-row .n, .num-row h3, .num-row p { grid-column: 1 / 13; }
    .entry-row, .num-row { row-gap: 10px; }}
/* The hand matte goes from transparent to opaque in about two pixels, which
   reads as cut-and-paste on a pale ground. The asset itself is now feathered
   (eroded, colour edge-extended, then the alpha blurred -- blurring alone
   would have dragged the near-black panelling behind him into the feather
   and given him a dark outline). This shadow does the rest: offset down and
   to the right so it reads as light from one side, rather than the even halo
   a centred shadow puts around his head. */
.figure img {
    filter: drop-shadow(18px 22px 40px rgba(0, 0, 0, .16));
    /* The cut-out's opaque content runs right to the left, right and bottom
       edges of its canvas, so the frame cuts straight through his shoulders
       and his suit. Those are the straight lines, not the silhouette --
       measured, the silhouette itself only steps 1.02 to 1.28:1, which is
       already soft. This fades the canvas edges away so the slices dissolve
       into the page. The top of the canvas is transparent anyway, so the
       vignette costs nothing there, and the core stays solid well past his
       face. */
    -webkit-mask-image: radial-gradient(88% 98% at 50% 45%,
        #000 56%, rgba(0,0,0,.74) 76%, rgba(0,0,0,.26) 92%, transparent 100%);
            mask-image: radial-gradient(88% 98% at 50% 45%,
        #000 56%, rgba(0,0,0,.74) 76%, rgba(0,0,0,.26) 92%, transparent 100%);
}

/* ════════════════════════════════════════════════════════════════════
   Rebuilt architecture. Everything below overrides the single-grid
   layout that put every section in the same middle columns: the page
   was one flat column of grey with a dead margin down both sides.
   ════════════════════════════════════════════════════════════════════ */

/* ── The argument, set against the structure it describes ─────────── */
.split {
    display: grid; grid-template-columns: 42% minmax(0, 1fr); align-items: stretch;
    /* the rule belongs to the whole band: on .claim alone it stopped dead
       where the photograph started */
    border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.plate {
    margin: 0; position: relative; overflow: hidden;
    /* a min-height rather than an aspect-ratio: aspect-ratio on a flex or
       grid child renders correctly in Chromium and collapses to zero
       height in iOS Safari */
    min-height: clamp(300px, 34vw, 470px);
}
/* Positioned out of flow on purpose. With the image in normal flow,
   height:100% has no definite parent height to resolve against, so it
   silently falls back to the image's own aspect ratio and the band became
   806px tall -- exactly 605 x 1493/1120. min-height was only ever a floor,
   never a cap. Out of flow, the image fills whatever height the row ends up
   with, and the row is driven by the copy beside it. */
.plate img { position: absolute; inset: 0; width: 100%; height: 100%;
             object-fit: cover; display: block; }
.claim {
    display: flex; align-items: center;
    padding: clamp(34px, 4.4vw, 66px) clamp(22px, 3.4vw, 54px);
}
.claim .statement {
    grid-column: auto;            /* it is no longer on the 12-col grid */
    max-width: 26ch;
    font-size: clamp(22px, 2.5vw, 36px); line-height: 1.24;
}

/* ── Method, at full width ────────────────────────────────────────── */
.method-band .headline { grid-column: auto; max-width: 20ch; margin-bottom: clamp(18px, 2.4vw, 34px); }

/* ── A structural interval, full bleed ───────────────────────────── */
.interval { margin: 0; height: clamp(170px, 20vw, 300px); overflow: hidden; }
.interval { position: relative; }
.interval img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }

/* ── His words, on the one dark ground. Measured: white 14.79:1. ─── */
.voice { background: #1c2936; color: #fff; }
.voice .wrap { padding-block: clamp(40px, 5.4vw, 84px); }
.voice blockquote { max-width: min(100%, 980px); }
.voice blockquote p {
    font-size: clamp(23px, 3.1vw, 44px); font-weight: 400;
    line-height: 1.2; letter-spacing: -.026em;
}
.voice cite {
    display: block; margin-top: clamp(20px, 2.4vw, 32px); font-style: normal;
    font-size: 15px; font-weight: 600; color: #c3ccd4;
}

/* ── Study: heading on the left edge, prose in its own column ─────── */
.study-band .headline { grid-column: 1 / 6; margin-top: 0; max-width: 20ch; }
.study-band .principal { grid-column: 7 / 13; margin-top: 0; }

/* ── Applied to live work, at full width ─────────────────────────── */
.applied-band .headline { grid-column: auto; max-width: 22ch; }

/* the bands either side of the dark one do not need the full interval */
.method-band { padding-block: clamp(34px, 4.6vw, 72px); }
.study-band, .applied-band { padding-block: clamp(34px, 4.6vw, 72px); }

@media (max-width: 900px) {
    .split { grid-template-columns: minmax(0, 1fr); }
    .plate { min-height: clamp(240px, 58vw, 380px); }
    .claim { padding-inline: clamp(22px, 4vw, 64px); }
    .claim .statement { max-width: none; }
    .study-band .headline, .study-band .principal { grid-column: 1 / 13; }
    .study-band .principal { margin-top: clamp(16px, 2.4vw, 26px); }
}

/* ── LinkedIn mark in the footer ──────────────────────────────────────
   Inline SVG, so nothing is fetched and it inherits the footer's own
   link colour through currentColor. The link carries an aria-label
   because it now has no text, and keeps a 44px target: the glyph is
   19px, so the rest comes from padding. */
/* footer .legal a sets its own colour, so the mark needs to outrank it
   rather than rely on inheritance */
footer .legal a.social { display: inline-flex; align-items: center;
          justify-content: center; width: 44px; height: 44px;
          padding-block: 0; color: var(--ink); }
footer .legal a.social:hover { color: var(--brick); }
/* ── The footer icon row ───────────────────────────────────────────────
   One li holds every social mark, so the footer list's own column-gap
   separates the row from the text links while the marks themselves sit
   closer together, as an icon cluster should. The -11px pulls the first
   glyph out to the text edge: each mark is centred in a 44px tap
   target, so its ink starts about 11px in.
   NOTE: this belongs at SCREEN level. It was previously emitted inside
   @media print, where it did nothing, so the marks laid out as ragged
   inline content on screen. */
footer .legal .socials { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; margin-left: -11px; }

.social svg { display: block; }

/* ── Print. The dark quote band would otherwise print as a solid block. ── */


/* ── A thin rule under the name ──────────────────────────────────────── */
.head-rule { display: block; width: 62px; height: 2px; background: var(--brick);
             margin-top: clamp(14px, 1.8vw, 22px); }

/* ── The notice bar, straight under the hero ──────────────────────────
   Carries the one credential that distinguishes this domain. It states the
   in-progress dates in the same breath, because the rule is that the MSc
   can never read as held. Measured: white 14.79:1, the state line 9.09:1. */
.notice { background: #1c2936; color: #fff; }
.notice .wrap { padding-block: clamp(13px, 1.5vw, 18px); }
.notice p { font-size: clamp(14px, 1.35vw, 16px); line-height: 1.45; font-weight: 500; }
.notice .state { color: #c3ccd4; font-weight: 400; }

/* ── Areas of practice as pills ───────────────────────────────────────
   One tone for all four, not a graded ramp: a ramp would imply a ranking
   these four do not have. Measured on the pill: ink 10.95:1, and the pill
   itself registers against the paper at 1.41:1. */
/* .rail-band .rail ul sets a four-column grid, which outranks a plain
   .rail-pills ul and stretched every pill to the same width. Matching its
   specificity lets them hug their own labels, as a pill should. */
.rail-band .rail-pills ul {
    list-style: none; display: flex; flex-wrap: wrap;
    gap: clamp(8px, 1vw, 14px); grid-template-columns: none;
}
.rail-band .rail-pills li {
    background: #bccbd7; border: 1px solid rgba(47, 74, 99, .30);
    border-radius: 999px; border-top: 1px solid rgba(47, 74, 99, .30);
    padding: 11px clamp(16px, 1.8vw, 26px);
    font-size: clamp(14.5px, 1.4vw, 16.5px); font-weight: 600;
    letter-spacing: -.012em; color: var(--ink);
}

/* ── Corner brackets on the opening statement ────────────────────────── */
.bracketed { position: relative; }
.bracketed::before, .bracketed::after {
    content: ''; position: absolute; width: 22px; height: 22px;
    border-color: var(--rule); border-style: solid; border-width: 0;
}
.bracketed::before { top: clamp(14px, 2vw, 30px); left: clamp(8px, 1.4vw, 22px);
                     border-top-width: 1px; border-left-width: 1px; }
.bracketed::after { bottom: clamp(14px, 2vw, 30px); right: clamp(8px, 1.4vw, 22px);
                    border-bottom-width: 1px; border-right-width: 1px; }

/* Print comes last on purpose: these overrides are the same
   specificity as the rules they replace, so source order is the
   only thing that makes them win. */
@media print {
    :root {
        --paper: #ffffff; --ink: #111111; --body: #222222;
        --grey: #444444; --line: #bbbbbb; --rule: #999999; --brick: #000000;
    }
    body { background: #fff; color: #111; }
    .skip-link, .to-top, .interval, .plate, .backdrop { display: none; }
    .voice { background: #fff; color: #111; }
    /* the notice bar was added after this block was written, and printed
       white on white -- the exact failure the print check exists for */
    .notice { background: #fff; color: #111; border-block: 1px solid #bbb; }
    .notice p, .notice .state { color: #111; }
    .rail-band .rail-pills li { background: #fff; border-color: #999; }
    .voice blockquote p, .voice cite { color: #111; }
    .split { grid-template-columns: minmax(0, 1fr); }
    .figure img { filter: none; max-height: 90mm; width: auto; }
    a { text-decoration: underline; }
    footer .legal a.social svg { display: none; }
    footer .legal a.social { width: auto; height: auto; margin-left: 0; }
    footer .legal .socials { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-left: 0; }
    footer .legal a.social.social--li::after { content: "linkedin.com/in/anton-alexander-p-61447026a"; }
    footer .legal a.social.social--yt::after { content: "youtube.com/@AntonAlexanderPalmer"; }
    footer .legal a.social.social--cb::after { content: "crunchbase.com/person/anton-palmer-d904"; }
    footer .legal a.social.social--pin::after { content: "pinterest.com/antonalexanderpalmer"; }
    footer .legal a.social.social--fl::after { content: "flickr.com/people/antonalexanderpalmer"; }
    footer .legal a.social.social--md::after { content: "medium.com/@antonalexanderpalmer"; }
    footer .legal a.social.social--ss::after { content: "slideshare.net/info80645"; }
    footer .legal a.social.social--sd::after { content: "scribd.com/AntonAlexanderPalmer"; }
    footer .legal a.social.social--wp::after { content: "antonalexanderpalmer.wordpress.com"; }
    footer .legal a.social.social--bl::after { content: "antonalexanderpalmer.blogspot.com"; }
    footer .legal a.social.social--tb::after { content: "tumblr.com/antonalexanderpalmer"; }
    footer .legal a.social.social--wf::after { content: "anton-alexander-palmer.webflow.io"; }
    footer .legal a.social.social--lt::after { content: "linktr.ee/AntonAlexanderPalmer"; }
    footer .legal a.social.social--x::after { content: "x.com/Anton__Palmer"; }
    footer .legal a.social.social--fb::after { content: "facebook.com/AntonAlexanderPalmer"; }
    footer .legal a.social.social--ig::after { content: "instagram.com/antonalexanderpalmer"; }
}
