/* ===========================================================================
   shonairra.com
   Design system.

   Revision 04. The pattern is Amalfi lemon maiolica: cobalt and white tile
   medallions, lemons, leaves, on a cream ground. The interface is that
   pattern's palette pulled down into pastel, so the tiles are the loudest
   thing on any page and everything else gets out of their way.

   Every colour below is sampled from the artwork itself rather than guessed:
   the tile's own cobalt is #2A5CB0, its azure #4979C1, its lemon #F1D440, its
   leaf #7C964A, its ground #FCF7DD. The text tokens are those hues walked
   down in value until they clear 4.5:1 on all seven grounds this site uses.

   Rules carried through every revision:
     no shadow            separation is hairlines, colour and space
     no gradient          between hues, ever
     no icon library      words and rules do that work
     motion               clip wipes and composited transforms only, all of it
                          inside prefers-reduced-motion
   =========================================================================== */

:root{
  /* ---- grounds, all pastel ---- */
  --cream:  #FDFAF1;   /* page. the tile's own ground, a shade cooler */
  --sky:    #EAF1F8;   /* tint bands */
  --white:  #FFFFFF;

  /* ---- ink ---- */
  --ink:    #1E2A38;   /* 13.94 on cream, 11.94 on the darkest wash */
  --muted:  #626A72;   /* metadata. 4.51 at worst, so still AA at 11px */

  /* ---- accents. both cleared for body text on all seven grounds ---- */
  --blue:   #3368B7;   /* the tile's azure, walked down. 5.29 cream, 4.53 worst */
  --green:  #57703A;   /* the tile's leaf green.        5.32 cream, 4.56 worst */

  /* Lemon never carries text. At its own value it is 1.4:1 on cream, which is
     invisible; ink on lemon is 9.9:1, so type goes on top of it, never in it. */
  --lemon:  #F1D440;

  /* ---- pastel washes. panels and page heads. ink on any is above 11:1 ---- */
  --w-blue:  #DFEAF6;
  --w-lemon: #FBF3D6;
  --w-leaf:  #E8EEDF;
  --w-shell: #F6F0E4;

  /* ---- hairlines ---- */
  --rule:      #DCE4EC;
  --rule-firm: #B9C7D6;

  /* ---- type ---- */
  --display: 'Boska', Georgia, 'Times New Roman', serif;
  --body:    'Aspekta', 'Archivo', system-ui, -apple-system, sans-serif;
  --mono:    'Geist Mono', 'IBM Plex Mono', ui-monospace, 'SF Mono', monospace;

  --t-hero: clamp(52px, 10vw, 132px);
  --t-h2:   clamp(30px, 5vw,  58px);
  --t-h3:   clamp(20px, 2.4vw, 28px);
  --t-body: 16px;
  --t-meta: 11px;

  /* 8px baseline rhythm */
  --s1: 8px;   --s2: 16px;  --s3: 24px;  --s4: 32px;
  --s5: 40px;  --s6: 56px;  --s7: 72px;  --s8: 96px;  --s9: 128px;

  --maxw: 1240px;
  --gutter: 40px;

  --r: 4px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ===== Reset ============================================================= */

*,*::before,*::after{
  box-sizing:border-box;
  margin:0;
  padding:0;
}

html{
  -webkit-text-size-adjust:100%;
  scroll-behavior:auto;
}

body{
  background:var(--cream);
  color:var(--ink);
  font-family:var(--body);
  font-size:var(--t-body);
  line-height:1.62;
  font-weight:350;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow-x:hidden;
}

img,svg,canvas{display:block;max-width:100%}
img{height:auto}
ul,ol{list-style:none}
button,input,select,textarea{
  -webkit-appearance:none;
  appearance:none;
  font:inherit;
  color:inherit;
}
button{background:none;border:none;cursor:pointer}
table{border-collapse:collapse;width:100%}

/* ===== Focus ============================================================= */
/* 2px blue, 2px offset, everywhere. Focus is never suppressed on this
   site: the outline property is set here and nowhere else. */

:focus-visible{
  outline:2px solid var(--blue);
  outline-offset:2px;
}

.skip{
  position:absolute;
  left:var(--s3);
  top:-100px;
  z-index:200;
  background:var(--ink);
  color:var(--cream);
  padding:var(--s2) var(--s3);
  border-radius:var(--r);
  font-family:var(--mono);
  font-size:var(--t-meta);
  letter-spacing:.14em;
  text-transform:uppercase;
  transition:top 120ms var(--ease);
}
.skip:focus{top:var(--s3)}

/* ===== Type ============================================================== */

h1,h2,h3,.display{
  font-family:var(--display);
  font-weight:400;
  /* Boska is a high contrast face with a narrow set and takes tighter tracking
     than the fallback without the counters closing up. */
  letter-spacing:-0.035em;
  line-height:1.0;
  text-wrap:balance;
}

h1{font-size:var(--t-hero)}
h2{font-size:var(--t-h2)}
h3{font-size:var(--t-h3);line-height:1.12}

.mono,.meta{
  font-family:var(--mono);
  font-size:var(--t-meta);
  font-weight:400;
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--muted);
  line-height:1.5;
}
/* Muted carries this 11px uppercase layer and nothing else, never running
   text. #626A72 is the lightest blue grey that clears 4.5:1 on the cream, the
   sky and all four pastel washes, so the layer stays AA wherever a section
   decides to sit. */

.meta-blue{color:var(--blue)}
.meta-blue{color:var(--blue)}
.meta-green{color:var(--green)}
.meta-ink{color:var(--ink)}

p{max-width:64ch}
p + p{margin-top:var(--s2)}

.lede{
  font-size:19px;
  line-height:1.5;
  max-width:48ch;
  font-weight:350;
}

em,.italic{font-family:var(--display);font-style:italic}
b,strong{font-weight:600}

a{color:inherit;text-decoration:none}
.link{
  color:var(--blue);
  border-bottom:1px solid rgba(169,78,46,.36);
  transition:border-color 160ms var(--ease);
}
.link:hover{border-bottom-color:var(--blue)}

.figure{
  font-family:var(--display);
  font-size:clamp(64px,12vw,164px);
  line-height:0.86;
  letter-spacing:-0.05em;
  font-variant-numeric:lining-nums tabular-nums;
}

/* ===== Grid ============================================================== */

.wrap{
  width:100%;
  max-width:var(--maxw);
  margin:0 auto;
  padding:0 var(--gutter);
}

.grid{
  display:grid;
  grid-template-columns:repeat(12,1fr);
  gap:0 var(--s5);
}

.col-content{grid-column:1 / 8}
.col-wide{grid-column:1 / 11}
.col-full{grid-column:1 / -1}
.col-margin{grid-column:9 / 13}
.col-side{grid-column:8 / 13}

@media (max-width:900px){
  :root{--gutter:24px}
  .grid{gap:0 var(--s3)}
  .col-content,.col-wide,.col-margin,.col-side{grid-column:1 / -1}
}

/* ===== Hairlines and sections ============================================ */

.rule   {border-top:1px solid var(--rule)}
.rule-b {border-bottom:1px solid var(--rule)}

section{padding:var(--s8) 0}
section.tint{background:var(--sky)}
section.w-shell{background:var(--w-shell)}
section.w-blue{background:var(--w-blue)}
section.w-leaf{background:var(--w-leaf)}
section.w-lemon{background:var(--w-lemon)}

.sec-head{
  display:flex;
  gap:var(--s4);
  align-items:baseline;
  padding-bottom:var(--s2);
  border-bottom:1px solid var(--rule-firm);
  margin-bottom:var(--s6);
}
.sec-head .n{
  font-family:var(--mono);
  font-size:var(--t-meta);
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--blue);
  white-space:nowrap;
  padding-top:6px;
}
.sec-head.blue .n{color:var(--blue)}
.sec-head.green .n{color:var(--green)}
.sec-head h2{flex:1}

/* ===== Masthead ========================================================== */

.mast{
  position:sticky;
  top:0;
  z-index:60;
  background:var(--cream);
  border-bottom:1px solid var(--rule-firm);
}
.mast .wrap{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:var(--s3);
  padding-top:var(--s3);
  padding-bottom:var(--s2);
}
.mast a{font-family:var(--mono);font-size:var(--t-meta);letter-spacing:.14em;text-transform:uppercase}

/* Written as `.mast a.mast-name` because the `.mast a` rule above is one
   specificity step higher than a bare class and silently wins otherwise. */
.mast a.mast-name{
  font-family:var(--display);
  font-size:20px;
  line-height:1;
  letter-spacing:-0.01em;
  text-transform:none;
  color:var(--ink);
}
.mast nav ul{display:flex;gap:var(--s3);flex-wrap:wrap}
.mast nav a{
  color:var(--muted);
  padding-bottom:2px;
  border-bottom:1px solid transparent;
  transition:color 160ms var(--ease),border-color 160ms var(--ease);
}
.mast nav a:hover{color:var(--ink)}
.mast nav a[aria-current="page"]{color:var(--blue);border-bottom-color:var(--blue)}

/* ===== Dated lists ======================================================= */

.dated{border-top:1px solid var(--rule-firm)}
.dated > li,.dated > .row{
  display:grid;
  grid-template-columns:190px 1fr;
  gap:var(--s5);
  padding:var(--s3) 0;
  border-bottom:1px solid var(--rule);
  align-items:start;
}
.dated .when{
  font-family:var(--mono);
  font-size:var(--t-meta);
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--blue);
  padding-top:5px;
}
.dated.blue .when{color:var(--blue)}
.dated.green .when{color:var(--green)}
.dated .what{max-width:60ch}
.dated .what b{font-weight:600}

@media (max-width:700px){
  .dated > li,.dated > .row{grid-template-columns:1fr;gap:var(--s1)}
  .dated .when{padding-top:0}
}

.row-large{
  border-top:1px solid var(--rule-firm);
  border-bottom:1px solid var(--rule-firm);
  padding:var(--s6) 0;
  margin:var(--s6) 0;
}
.row-large h3{
  font-size:clamp(26px,4.4vw,50px);
  margin:var(--s2) 0 var(--s3);
  max-width:22ch;
}

/* definition table */
.deflist{border-top:1px solid var(--rule-firm)}
.deflist div{
  display:grid;
  grid-template-columns:190px 1fr;
  gap:var(--s5);
  padding:var(--s3) 0;
  border-bottom:1px solid var(--rule);
}
.deflist dt{
  font-family:var(--mono);
  font-size:var(--t-meta);
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--muted);
  padding-top:5px;
}
.deflist dd{max-width:60ch}
@media (max-width:700px){
  .deflist div{grid-template-columns:1fr;gap:var(--s1)}
  .deflist dt{padding-top:0}
}

/* ---- Draft annotations --------------------------------------------------
   TODO chips and their notes are build instrumentation, not content. Hidden
   by default; visible only when <html data-draft> is present. deploy.sh
   strips data-draft from the public build and reveal.js restores it when the
   URL carries ?draft=1, so every open item stays readable on the live URL
   without the client ever seeing one.

   !important is deliberate and is the whole point. This is the rule that
   stops internal notes reaching the client, so it must not be losable to a
   specificity accident elsewhere in the sheet. A first pass without it was
   beaten by two ordinary display rules and sixteen chips shipped. */
.todo{
  font-family:var(--mono);
  font-size:var(--t-meta);
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--blue);
  border:1px solid var(--blue);
  border-radius:var(--r);
  padding:2px 8px;
}

.todo,
.note-todo,
[data-draft-only]{display:none !important}
.note:has(.todo){display:none !important}

[data-draft] .todo{display:inline-block !important}
[data-draft] .note-todo{display:block !important}
[data-draft] [data-draft-only]{display:revert !important}
[data-draft] .note:has(.todo){display:block !important}

/* ===== Photography =======================================================
   Photographs run in colour. Against a pastel ground a colour photograph of a
   school hall is the warm thing on the page, and desaturating it would undo
   the direction. All that is left is a card and a hairline. */

.photo{
  position:relative;
  display:block;
  overflow:hidden;
  background:var(--sky);
  border-radius:var(--r);
}
.photo img{width:100%;display:block}

.figcap{
  font-family:var(--mono);
  font-size:var(--t-meta);
  letter-spacing:0.14em;
  text-transform:uppercase;
  color:var(--muted);
  padding-top:var(--s2);
  line-height:1.6;
}

/* ===== Motion ============================================================
   Everything below is inside prefers-reduced-motion: no-preference.
   Under reduce nothing animates and everything is simply present.
   ========================================================================= */

@media (prefers-reduced-motion: no-preference){

  .reveal > .line,
  .reveal-item{
    clip-path:inset(0 0 100% 0);
    will-change:clip-path;
  }
  /* The open state insets negatively at the bottom and sides. Display type
     runs at a line height of 1.0, so descenders and overhanging italics sit
     outside the line box and clipping to inset(0) slices the tail off every
     y and g in a headline. */
  .reveal.is-in > .line,
  .reveal-item.is-in{
    clip-path:inset(0 -0.06em -0.34em -0.06em);
    transition:clip-path 380ms var(--ease);
  }
  .reveal.is-in > .line:nth-child(1){transition-delay:0ms}
  .reveal.is-in > .line:nth-child(2){transition-delay:60ms}
  .reveal.is-in > .line:nth-child(3){transition-delay:120ms}
  .reveal.is-in > .line:nth-child(4){transition-delay:180ms}
  .reveal.is-in > .line:nth-child(5){transition-delay:240ms}
  .reveal.is-in > .line:nth-child(6){transition-delay:300ms}

  .wipe{clip-path:inset(0 100% 0 0)}
  .wipe.is-in{clip-path:inset(0 0 0 0);transition:clip-path 520ms var(--ease)}
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:0.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:0.001ms !important;
    scroll-behavior:auto !important;
  }
  .reveal > .line,.reveal-item,.wipe{clip-path:none !important}
}

/* ===== Buttons =========================================================== */

.btn{
  font-family:var(--mono);
  font-size:var(--t-meta);
  letter-spacing:0.14em;
  text-transform:uppercase;
  border:1px solid var(--ink);
  border-radius:var(--r);
  color:var(--ink);
  padding:var(--s2) var(--s3);
  display:inline-block;
  transition:background-color 160ms var(--ease), color 160ms var(--ease);
}
.btn:hover{background:var(--ink);color:var(--cream)}
.btn-blue{border-color:var(--blue);color:var(--blue)}
.btn-blue:hover{background:var(--blue);color:var(--cream)}

.btn-row{display:flex;gap:var(--s2);flex-wrap:wrap;margin-top:var(--s5)}

/* ===== Footer ============================================================ */

.site-foot{
  border-top:1px solid var(--rule-firm);
  padding:var(--s6) 0 var(--s7);
}
.site-foot .wrap{
  display:flex;
  justify-content:space-between;
  gap:var(--s3);
  flex-wrap:wrap;
}
.site-foot a{color:var(--muted);transition:color 160ms var(--ease)}
.site-foot a:hover{color:var(--blue)}

/* Lines produced by reveal.js splitting on <br>. They must stack, or the
   author's line breaks vanish when the spans are inserted. */
.reveal .line{display:block}

.note{
  border-left:2px solid var(--blue);
  padding-left:var(--s2);
  font-size:14px;
  max-width:56ch;
  margin-top:var(--s3);
}
