/* ==========================================================================
   Tokens. Change these six colours and the whole site changes with them.
   ========================================================================== */
:root{
  --canvas:#E4E6EA;      /* page background */
  --panel:#FFFFFF;       /* cards, media frames */
  --ink:#14161C;         /* text */
  --muted:#5B6170;       /* secondary text */
  --line:#C2C7D0;        /* hairlines and borders */
  --accent:#2323D8;      /* links, focus, the one loud colour */
  --on-accent:#FFFFFF;

  --font-display:"Archivo","Helvetica Neue",Arial,system-ui,sans-serif;
  --font-prose:"Source Serif 4",Georgia,"Times New Roman",serif;

  --gutter:clamp(1.15rem,4vw,3rem);
  --measure:34rem;
  --slider-ratio:16/9;    /* shape of the slideshow frame on project pages. Try 2/1 for wide stills, 4/3 for squarer ones */
  --flow-measure:42rem;   /* width of the text on project and note pages. Try 38rem (narrower) to 46rem (wider) */
  color-scheme:light;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --canvas:#0F1116; --panel:#191C24; --ink:#ECEEF3; --muted:#969DAE;
    --line:#2C313D; --accent:#8C8CFF; --on-accent:#0F1116;
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --canvas:#0F1116; --panel:#191C24; --ink:#ECEEF3; --muted:#969DAE;
  --line:#2C313D; --accent:#8C8CFF; --on-accent:#0F1116;
  color-scheme:dark;
}

/* ==========================================================================
   Base
   ========================================================================== */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--canvas);color:var(--ink);
  font-family:var(--font-display);font-size:1.0625rem;line-height:1.55;
  font-variation-settings:"wdth" 100;
  -webkit-font-smoothing:antialiased;
}
img,video{max-width:100%;height:auto;display:block}
a{color:inherit}
a:hover{color:var(--accent)}
:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
main:focus{outline:none}
h1,h2,h3{margin:0;letter-spacing:-.025em;line-height:1.05;font-weight:700}
.skip{position:absolute;left:1rem;top:-5rem;z-index:20;background:var(--accent);color:var(--on-accent);padding:.65rem 1rem;font-weight:600;text-decoration:none}
.skip:focus{top:1rem}

/* ==========================================================================
   Chrome
   ========================================================================== */
.topbar{
  display:flex;justify-content:space-between;align-items:baseline;gap:1rem 2rem;
  flex-wrap:wrap;padding:1.15rem var(--gutter);
}
.brand{
  font-weight:800;font-size:1.35rem;letter-spacing:-.01em;text-decoration:none;
  font-variation-settings:"wdth" 112;
}
.nav{display:flex;gap:1.35rem;font-weight:500}
.nav a{text-decoration:none;padding-bottom:2px;border-bottom:2px solid transparent}
.nav a:hover{border-color:var(--accent)}
.nav a[aria-current="page"]{border-color:var(--ink)}

.footer{margin-top:clamp(4rem,10vw,8rem);border-top:1px solid var(--line)}
.footer-inner{
  padding:2rem var(--gutter) 3rem;display:flex;flex-wrap:wrap;
  gap:.75rem 2.5rem;align-items:baseline;
}
.footer-links{margin:0;display:flex;flex-wrap:wrap;gap:1rem}
.footer-links a{text-decoration:none;color:var(--muted)}
.footer-links a:hover{color:var(--accent)}
.footer-fine{margin:0;color:var(--muted);font-size:.9rem;flex:1 1 100%}

/* ==========================================================================
   Masthead. Full width: the video runs edge to edge of the browser.
   ========================================================================== */
.masthead{position:relative;margin:0;isolation:isolate}
.masthead-media{
  position:relative;width:100%;
  height:min(78vh,56.25vw);   /* 16:9 on narrow windows, capped on wide ones */
  min-height:28rem;           /* keeps room for the headline on phones */
  overflow:hidden;background:#0B0C10;border-radius:0;
}
.masthead-media video{width:100%;height:100%;object-fit:cover}
.masthead-media::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(to top,rgba(8,9,12,.88) 0%,rgba(8,9,12,.35) 42%,rgba(8,9,12,.08) 75%);
}
.masthead-text{
  position:absolute;left:0;right:0;bottom:0;z-index:1;
  padding:0 var(--gutter) clamp(1.5rem,4vw,3rem);color:#fff;
}
.masthead-text h1{
  font-size:clamp(2.1rem,6.2vw,5.25rem);font-weight:800;
  font-variation-settings:"wdth" 92;max-width:14ch;text-wrap:balance;
}
.masthead-text p{margin:.9rem 0 0;max-width:38ch;font-size:clamp(1rem,1.6vw,1.25rem);color:rgba(255,255,255,.88)}
.masthead-caption{margin:.6rem 0 0;padding:0 var(--gutter);color:var(--muted);font-size:.85rem}

/* ==========================================================================
   Sections and the project grid
   ========================================================================== */
.section{padding:clamp(3.5rem,8vw,6.5rem) var(--gutter) 0}
.section-head{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;flex-wrap:wrap;margin-bottom:1.75rem}
.section h2{font-size:clamp(1.5rem,3vw,2.15rem)}
.more{font-weight:600;text-decoration:none;border-bottom:2px solid var(--accent)}

.page-head{padding:clamp(1.5rem,4vw,3rem) var(--gutter) clamp(1.75rem,4vw,2.75rem)}
.page-head h1{font-size:clamp(2.25rem,6vw,4.25rem);font-variation-settings:"wdth" 95;max-width:18ch;text-wrap:balance}
.page-head p{margin:1rem 0 0;color:var(--muted);max-width:var(--measure)}
.page-head .lede{color:var(--ink);font-size:clamp(1.1rem,2vw,1.35rem);max-width:40ch}
.page-head .stamp{margin:0 0 .75rem;color:var(--muted)}

.grid{
  display:grid;grid-template-columns:repeat(6,1fr);
  gap:clamp(.75rem,1.6vw,1.4rem);
  padding:0 var(--gutter);
}
.tile{grid-column:span 3;text-decoration:none;display:block;position:relative}
.tile:hover{color:inherit}
.tile-wide{grid-column:span 6}
.tile-tall{grid-column:span 3}
.tile-frame{
  display:block;position:relative;overflow:hidden;background:var(--panel);
  border:1px solid var(--line);border-radius:3px;aspect-ratio:16/9;
}
.tile-tall .tile-frame{aspect-ratio:4/5}
.tile-wide .tile-frame{aspect-ratio:21/9}
.tile-media{width:100%;height:100%;object-fit:cover}

/* Rollover loop: sits on top of the still, invisible until it is actually playing */
.tile-loop{position:absolute;inset:0;opacity:0;transition:opacity .2s ease}
.is-playing .tile-loop{opacity:1}

/* Title and details: centred on the thumbnail, shown on hover or keyboard focus.
   The soft dark patch sits behind the words only, so the loop stays visible at the edges. */
.tile-text{
  position:absolute;inset:0;z-index:2;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.3rem;
  padding:1rem;text-align:center;color:#fff;border-radius:3px;
  background:radial-gradient(ellipse at center,rgba(8,9,12,.62) 0%,rgba(8,9,12,.34) 55%,rgba(8,9,12,.1) 100%);
  text-shadow:0 1px 14px rgba(0,0,0,.55);
  opacity:0;transition:opacity .2s ease;pointer-events:none;
}
.tile:hover .tile-text,.tile:focus-visible .tile-text{opacity:1}
.tile-title{display:block;font-weight:700;font-size:clamp(1.15rem,2vw,1.7rem);letter-spacing:-.02em;line-height:1.1}
.tile-meta{display:block;font-size:.95rem;color:rgba(255,255,255,.88)}

/* Touch screens cannot hover, so the details sit along the bottom edge instead */
@media (hover:none){
  .tile-text{
    inset:auto 0 0 0;align-items:flex-start;text-align:left;opacity:1;
    padding:1.75rem .95rem .8rem;border-radius:0 0 3px 3px;
    background:linear-gradient(to top,rgba(8,9,12,.78),rgba(8,9,12,0));
  }
}
@media (max-width:860px){
  .grid{grid-template-columns:repeat(2,1fr)}
  .tile,.tile-tall{grid-column:span 1}
  .tile-wide{grid-column:span 2}
}
@media (max-width:540px){
  .grid{grid-template-columns:1fr}
  .tile,.tile-tall,.tile-wide{grid-column:span 1}
  .tile-tall .tile-frame,.tile-wide .tile-frame{aspect-ratio:16/9}
}

/* ==========================================================================
   Prose
   ========================================================================== */
.prose{font-family:var(--font-prose);font-size:1.15rem;line-height:1.62;max-width:var(--measure)}
.prose p{margin:0 0 1.15em}
.prose h2{font-family:var(--font-display);font-size:1.45rem;margin:2.2rem 0 .7rem}
.prose h3{font-family:var(--font-display);font-size:1.15rem;margin:1.8rem 0 .5rem}
.prose ul,.prose ol{margin:0 0 1.15em;padding-left:1.3em}
.prose li{margin-bottom:.4em}
.prose a{color:var(--accent)}
.prose img{margin:1.75rem 0;border:1px solid var(--line);border-radius:3px;width:100%}
.prose blockquote{
  margin:1.75rem 0;padding-left:1.1rem;border-left:3px solid var(--accent);
  font-size:1.3rem;line-height:1.4;font-style:italic;
}
.prose blockquote p{margin:0}
.prose pre{
  background:var(--panel);border:1px solid var(--line);border-radius:3px;
  padding:1rem;overflow-x:auto;font-size:.95rem;
}
.prose code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.92em}
.prose hr{border:0;border-top:1px solid var(--line);margin:2.5rem 0}
.prose iframe{width:100%;aspect-ratio:16/9;height:auto;border:0;margin:1.75rem 0}

/* A page of free-form writing (a project or a note). Text keeps a readable width;
   videos and grids of stills run the full width of the page. */
.flow{max-width:none;padding:0 var(--gutter)}
.flow > *{max-width:var(--flow-measure)}
.flow > .embed,.flow > .slider,.flow > figure,.flow > pre{max-width:none}
.about{max-width:none}
.about .prose{margin-top:1.25rem}

/* ==========================================================================
   Project page
   ========================================================================== */
.back{display:inline-block;margin:0 var(--gutter);font-weight:600;text-decoration:none;border-bottom:2px solid var(--line)}
.embed{margin:0 var(--gutter);background:#0B0C10;border-radius:3px;overflow:hidden}
.embed iframe,.embed video{width:100%;aspect-ratio:16/9;height:auto;border:0;display:block}
.embed-empty img{width:100%;aspect-ratio:16/9;object-fit:cover}
.flow > .embed{margin:2rem 0}

/* Year, discipline and credits, in a strip under the main video */
.credits{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(11rem,1fr));gap:1rem 2rem;
  margin:1.5rem var(--gutter) 0;padding-top:1.1rem;border-top:1px solid var(--line);font-size:.95rem;
}
.credits div{min-width:0}
.credits dt{color:var(--muted)}
.credits dd{margin:0;font-weight:600;overflow-wrap:anywhere}
.embed + .flow,.credits + .flow{margin-top:clamp(2rem,5vw,3.5rem)}

/* Stills and video files inside a write-up */
.media{margin:2rem 0}
.media img,.media video{
  display:block;width:100%;height:auto;margin:0;
  border:1px solid var(--line);border-radius:3px;background:var(--panel);
}
.media figcaption{margin-top:.55rem;font-family:var(--font-display);font-size:.9rem;line-height:1.4;color:var(--muted)}
.zoom{display:block;cursor:zoom-in;text-decoration:none}
.zoom:hover{background:none}

/* Consecutive stills form a slideshow: one image at a time, in one frame, with buttons over it.
   Without JavaScript the images simply stack, one under another. */
.slider{margin:2rem 0}
.slider .slide{margin:0 0 1.25rem}
.slider .slide:last-child{margin-bottom:0}

.slider.is-ready .slider-stage{
  position:relative;aspect-ratio:var(--slider-ratio);overflow:hidden;
  background:#0B0C10;border-radius:3px;touch-action:pan-y pinch-zoom;
}
.slider.is-ready .slide{
  position:absolute;inset:0;margin:0;opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .3s ease,visibility 0s linear .3s;
}
.slider.is-ready .slide.is-active{opacity:1;visibility:visible;pointer-events:auto;z-index:1;transition:opacity .3s ease}
.slider.is-ready .slide figcaption{display:none}
.slider.is-ready .slide .zoom{height:100%}
.slider.is-ready .slide img,.slider.is-ready .slide video{
  width:100%;height:100%;object-fit:contain;border:0;border-radius:0;background:transparent;
}
.slider-stage :focus-visible{outline:3px solid #fff;outline-offset:-3px}

.slider-btn{
  position:absolute;top:50%;z-index:2;transform:translateY(-50%);
  display:grid;place-items:center;width:3.5rem;height:4.5rem;padding:0;
  color:#fff;background:none;border:0;cursor:pointer;
  opacity:.85;transition:opacity .2s ease;
}
.slider-btn:hover{opacity:1}
.slider-btn:focus-visible{outline:3px solid #fff;box-shadow:0 0 0 6px rgba(8,9,12,.6);border-radius:2px;opacity:1}
.slider-btn svg{
  width:2rem;height:2rem;
  filter:drop-shadow(0 0 1px rgba(0,0,0,.9)) drop-shadow(0 0 4px rgba(0,0,0,.6)) drop-shadow(0 2px 10px rgba(0,0,0,.45));
}
.slider-prev{left:.25rem}
.slider-next{right:.25rem}

.slider-bar{
  display:flex;justify-content:space-between;align-items:baseline;gap:1rem;margin-top:.6rem;
  font-family:var(--font-display);font-size:.9rem;line-height:1.4;color:var(--muted);
}
.slider-caption{margin:0;flex:1;min-width:0;min-height:1.4em}
.slider-count{margin:0;white-space:nowrap;font-variant-numeric:tabular-nums}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media (prefers-reduced-motion: reduce){
  .slider.is-ready .slide,.slider.is-ready .slide.is-active{transition:none}
}

/* Click-to-enlarge viewer */
html.lightbox-open{overflow:hidden}
.lightbox{
  border:0;padding:0;margin:0;inset:0;width:100vw;height:100vh;max-width:none;max-height:none;
  background:transparent;color:#fff;
}
.lightbox::backdrop{background:rgba(8,9,12,.94)}
.lightbox-stage{
  position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:.8rem;padding:4rem 5.5rem 1.5rem;
}
.lightbox img{
  display:block;width:auto;height:auto;max-width:100%;max-height:calc(100vh - 8rem);
  object-fit:contain;border:0;border-radius:2px;margin:0;
}
.lightbox-caption{margin:0;min-height:1.4em;font-family:var(--font-display);font-size:.95rem;color:rgba(255,255,255,.85);text-align:center}
.lightbox button{
  position:absolute;z-index:1;font:600 1rem var(--font-display);color:#fff;
  background:rgba(255,255,255,.12);border:2px solid rgba(255,255,255,.45);border-radius:2px;
  padding:.65rem 1.05rem;cursor:pointer;
}
.lightbox button:hover{border-color:#fff;background:rgba(255,255,255,.22)}
.lightbox :focus-visible{outline:3px solid #fff;outline-offset:2px}
.lightbox-close{top:1rem;right:1rem}
.lightbox-prev,.lightbox-next{top:50%;transform:translateY(-50%)}
.lightbox-prev{left:1rem}
.lightbox-next{right:1rem}
@media (max-width:640px){
  .lightbox-stage{padding:4rem .75rem 5rem}
  .lightbox-prev,.lightbox-next{top:auto;bottom:1rem;transform:none}
  .lightbox img{max-height:calc(100vh - 11rem)}
}

.next,.post-nav a{
  display:block;text-decoration:none;border-top:1px solid var(--ink);
  margin:clamp(3rem,7vw,5rem) var(--gutter) 0;padding-top:1.1rem;
}
.next span,.post-nav span{display:block;color:var(--muted);font-size:.9rem}
.next strong,.post-nav strong{
  display:block;font-size:clamp(1.6rem,4vw,2.5rem);font-weight:700;letter-spacing:-.025em;
}
.next:hover strong,.post-nav a:hover strong{color:var(--accent)}
.post-nav{display:grid;gap:0}

/* ==========================================================================
   Notes list and contact
   ========================================================================== */
.notes{list-style:none;margin:0;padding:0 var(--gutter);border-top:1px solid var(--line)}
.notes li{border-bottom:1px solid var(--line)}
.notes a{display:grid;grid-template-columns:minmax(0,1fr);gap:1rem 2rem;padding:1.4rem 0;text-decoration:none;align-items:start}
.notes.has-thumbs a{grid-template-columns:minmax(0,18rem) minmax(0,1fr)}
.note-thumb{display:block;position:relative;aspect-ratio:16/9;overflow:hidden;background:var(--panel);border:1px solid var(--line);border-radius:3px}
.note-thumb img{display:block;width:100%;height:100%;object-fit:cover}
.note-thumb video{display:block}
.note-text{display:block;min-width:0}
.notes time{display:block;margin-bottom:.3rem;color:var(--muted);font-size:.92rem}
.notes strong{display:block;font-size:1.4rem;font-weight:700;letter-spacing:-.02em;line-height:1.15}
.notes a:hover strong{color:var(--accent)}
.note-summary{display:block;margin-top:.5rem;max-width:var(--flow-measure);color:var(--muted);font-family:var(--font-prose);font-size:1.05rem}
@media (max-width:640px){
  .notes.has-thumbs a{grid-template-columns:1fr}
}

/* A button-style link, used for "Get it on Gumroad" and similar on tool pages */
.post-link{margin:0 var(--gutter) clamp(1.5rem,4vw,2.5rem)}
.button{
  display:inline-block;background:var(--ink);color:var(--canvas);font-weight:700;
  padding:.8rem 1.4rem;border-radius:2px;text-decoration:none;
}
.button:hover{background:var(--accent);color:var(--on-accent)}
.tags{padding:1.5rem var(--gutter) 0;color:var(--muted);font-size:.9rem}
.empty{padding:0 var(--gutter);color:var(--muted)}

.contact-body{padding:0 var(--gutter)}
.mail{margin:0 0 1.25rem}
.mail a{
  font-weight:800;font-size:clamp(1.6rem,6vw,3.75rem);letter-spacing:-.03em;
  font-variation-settings:"wdth" 95;text-decoration:none;overflow-wrap:anywhere;
  border-bottom:3px solid var(--accent);
}
.contact-note{margin:0 0 2rem;color:var(--muted);max-width:var(--measure)}
.link-list{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:.6rem}
.link-list a{display:inline-block;text-decoration:none;font-weight:600;border:2px solid var(--line);border-radius:2px;padding:.55rem 1rem}
.link-list a:hover{border-color:var(--accent)}

@media (prefers-reduced-motion: reduce){
  *{animation-duration:.01ms !important;transition-duration:.01ms !important}
}
