/* ==========================================================================
   home.bystanek.com
   Built on the Mellow design system (see "Mellow design sysem — bystanek.com/").
   Tokens below are copied from that system's tokens/*.css so this page stays a
   single file with no imports. Two deliberate changes from the source system:

     1. Fonts. Mellow specifies Instrument Serif / Karla / IBM Plex Mono from
        Google Fonts. This page loads nothing external, so the token names are
        kept and pointed at system stacks instead. Swap the three --font-* values
        back to the real families if you ever self-host them.
     2. Widths. --wrap is 600px here, not Mellow's 760px, because a link list
        reads better narrow.

   Mellow rules kept intact: radius 0 everywhere, hairlines instead of shadows,
   sienna as the only accent, dark mode desaturates rather than inverts.
   ========================================================================== */

:root{
  /* base — linen paper (hue ~38, very low chroma) */
  --linen-50:#F7F3ED; --linen-100:#F1EBE1; --linen-200:#EAE1D3; --linen-300:#E4DFD6;
  /* base — ink, near neutral on purpose */
  --ink-900:#1F1E1D; --ink-600:#57544F; --ink-500:#6E6B66; --ink-400:#8A8579;
  /* base — night ground, neutral charcoal */
  --night-900:#1F1F1F; --night-800:#262626; --night-700:#343434;
  --night-ink:#ECEAE7; --night-muted:#9E9C99; --night-label:#B2AFAC;
  /* base — sienna */
  --sienna-900:#96412A; --sienna-800:#B34F33; --sienna-700:#CF5C40;
  --sienna-600:#E6775C; --sienna-400:#EE9A83; --sienna-300:#F4B5A1;

  /* semantic */
  --surface-page:var(--linen-50);
  --surface-raised:var(--linen-100);
  --surface-raised-hover:var(--linen-200);
  --text-body:var(--ink-900);
  --text-muted:var(--ink-500);
  --text-label:var(--ink-600);
  --text-quiet:var(--ink-400);
  --border-hairline:var(--linen-300);
  --accent-text:var(--sienna-800);
  --accent-text-hover:var(--sienna-900);
  --focus-ring:var(--sienna-800);
  --glow-near:rgba(230,119,92,.16);
  --glow-far:rgba(230,119,92,.08);
  color-scheme:light;

  /* type — Mellow's scale, system families */
  --font-display:Georgia,"Times New Roman",Times,serif;
  --font-body:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --font-mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  --size-display:clamp(34px,8vw,52px);
  --size-lede:clamp(19px,2.4vw,22px);
  --size-body:clamp(17px,2.1vw,18px);
  --size-body-sm:clamp(15px,2vw,15.5px);
  --size-ui:16px;
  --size-label:12px;

  --leading-display:1.06;
  --leading-body:1.72;
  --leading-lede:1.6;
  --tracking-display:-.01em;
  --tracking-label:.1em;
  --measure-narrow:58ch;

  /* space */
  --space-1:8px; --space-2:12px; --space-3:16px; --space-4:24px;
  --space-5:32px; --space-6:44px; --space-7:64px;
  --gutter:clamp(20px,5vw,32px);
  --wrap:600px;
  --tap-min:44px;
  --control-h-sm:32px;
  --tap-px:14px;

  /* shape — Mellow is a square system */
  --radius:0;
  --hairline:1px solid var(--border-hairline);
  --border-w:1px;
  --focus-width:2px;
  --focus-offset:4px;

  /* motion */
  --ease:cubic-bezier(.25,.1,.25,1);
  --reveal-duration:300ms;
  --reveal-travel:20px;
  --reveal-blur:4px;
  --micro:150ms;
  --ambient:26s;
}

/* Dark is not an inversion. Neutrals lose most of their chroma and the accent
   text value lifts to sienna-400 so it clears 4.5:1 on charcoal. */
:root[data-theme="dark"]{
  --surface-page:var(--night-900);
  --surface-raised:var(--night-800);
  --surface-raised-hover:#2E2E2E;
  --text-body:var(--night-ink);
  --text-muted:var(--night-muted);
  --text-label:var(--night-label);
  --text-quiet:#8B8987;
  --border-hairline:var(--night-700);
  --accent-text:var(--sienna-400);
  --accent-text-hover:var(--sienna-300);
  --focus-ring:var(--sienna-400);
  --glow-near:rgba(230,119,92,.11);
  --glow-far:rgba(230,119,92,.055);
  color-scheme:dark;
}

@media (pointer:coarse){
  :root{--control-h-sm:var(--tap-min);--tap-px:16px}
}

/* --- base ---------------------------------------------------------------- */

*,*::before,*::after{box-sizing:border-box}

html{-webkit-font-smoothing:antialiased;text-size-adjust:100%;-webkit-text-size-adjust:100%}

body{
  margin:0;
  background:var(--surface-page);
  color:var(--text-body);
  font:400 var(--size-body)/var(--leading-body) var(--font-body);
  text-wrap:pretty;
  overflow-x:hidden;
}

img,svg{max-width:100%;height:auto}

a{color:var(--accent-text);text-decoration:none;transition:color var(--micro) var(--ease)}
a:hover{color:var(--accent-text-hover)}
a,button{-webkit-tap-highlight-color:transparent;touch-action:manipulation}

h1{font-family:var(--font-display);font-weight:400;letter-spacing:var(--tracking-display);margin:0}

:focus-visible{
  outline:var(--focus-width) solid var(--focus-ring);
  outline-offset:var(--focus-offset);
  border-radius:var(--radius);
}

::selection{background:var(--sienna-600);color:#2B1610}

.label{
  font:500 var(--size-label)/1 var(--font-mono);
  letter-spacing:var(--tracking-label);
  text-transform:uppercase;
  color:var(--text-label);
}

.skip{
  position:absolute;left:-9999px;top:0;
  padding:var(--space-2) var(--space-3);
  background:var(--surface-raised);color:var(--text-body);
  font:500 var(--size-ui)/1 var(--font-body);
}
.skip:focus{left:var(--gutter);top:var(--space-2);z-index:10}

/* --- ambient glow -------------------------------------------------------- */
/* The one slow loop in the system. A 26s full-bleed repaint is a battery cost
   on phones for something nobody looks at, so touch gets it static. */

.glow{
  position:fixed;
  left:-12%;right:-12%;top:-24%;height:1100px;
  pointer-events:none;z-index:-1;
  background:
    radial-gradient(42% 34% at 32% 26%,var(--glow-near),transparent 72%),
    radial-gradient(52% 30% at 66% 62%,var(--glow-far),transparent 74%);
  animation:drift var(--ambient) var(--ease) infinite alternate;
}
@keyframes drift{
  from{transform:translate3d(-3%,-2%,0) scale(1)}
  to{transform:translate3d(5%,3%,0) scale(1.1)}
}
@media (pointer:coarse){.glow{animation:none}}

/* --- layout -------------------------------------------------------------- */

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

.topbar{
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--space-4);
  padding:var(--space-4) 0;
}

.toggle{
  appearance:none;background:none;cursor:pointer;
  display:inline-flex;align-items:center;
  height:var(--control-h-sm);padding:0 var(--tap-px);
  border:var(--border-w) solid var(--border-hairline);
  border-radius:var(--radius);
  color:var(--text-label);
  font:500 var(--size-label)/1 var(--font-mono);
  letter-spacing:var(--tracking-label);text-transform:uppercase;
  transition:color var(--micro) var(--ease),border-color var(--micro) var(--ease),opacity var(--micro) var(--ease);
}
.toggle:hover{color:var(--accent-text);border-color:var(--accent-text)}
.toggle:active{opacity:.72}

/* --- hero ---------------------------------------------------------------- */

.hero{padding:var(--space-6) 0 var(--space-7)}

.avatar{
  width:120px;height:120px;
  border-radius:50%; /* the one round thing on the page, and only because it is a face */
  object-fit:cover;
  display:block;
  background:var(--surface-raised);
  margin-bottom:var(--space-4);
}

.hero h1{
  font-size:var(--size-display);
  line-height:var(--leading-display);
  margin-bottom:var(--space-3);
}

.lede{
  margin:0 0 var(--space-4);
  font-size:var(--size-lede);
  line-height:var(--leading-lede);
  color:var(--text-body);
  max-width:var(--measure-narrow);
}

.bio{
  margin:0;
  font-size:var(--size-body-sm);
  line-height:var(--leading-body);
  color:var(--text-muted);
  max-width:var(--measure-narrow);
}

/* --- links --------------------------------------------------------------- */
/* Separation is space and a hairline. Mellow has no drop shadows, so the press
   state is a small translate and a background change, not a lift. */

.links{border-top:var(--hairline)}

.row{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;
  gap:var(--space-3);
  padding:var(--space-4) var(--space-3);
  margin-left:calc(var(--space-3) * -1);
  margin-right:calc(var(--space-3) * -1);
  border-bottom:var(--hairline);
  color:var(--text-body);
  min-height:var(--tap-min);
  transition:background-color var(--micro) var(--ease),
             color var(--micro) var(--ease),
             transform var(--micro) var(--ease);
}
.row:hover{background:var(--surface-raised);color:var(--text-body)}
.row:active{background:var(--surface-raised-hover);transform:translateY(1px)}

.ico{
  display:grid;place-items:center;
  width:24px;height:24px;
  color:var(--text-quiet);
  transition:color var(--micro) var(--ease);
}
.row:hover .ico{color:var(--accent-text)}
.ico svg{width:24px;height:24px;display:block}

.txt{display:flex;flex-direction:column;gap:2px;min-width:0}

.title{
  font:500 var(--size-ui)/1.3 var(--font-body);
  transition:color var(--micro) var(--ease);
}
.row:hover .title{color:var(--accent-text)}

.sub{
  font-size:var(--size-body-sm);
  line-height:1.35;
  color:var(--text-muted);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* Mellow would use --text-quiet here, but at 12px that lands on 3.3:1 in light
   mode. --text-label is the next step up and clears 4.5:1 in both themes. */
.tag{
  font:500 var(--size-label)/1 var(--font-mono);
  letter-spacing:var(--tracking-label);
  text-transform:uppercase;
  color:var(--text-label);
  white-space:nowrap;
}

/* Tags are the first thing to go when there is genuinely no room. 340px is
   below every current phone, so in practice they stay. */
@media (max-width:340px){
  .tag{display:none}
}

/* --- footer -------------------------------------------------------------- */

.foot{
  display:flex;flex-wrap:wrap;align-items:baseline;
  gap:var(--space-2) var(--space-5);
  border-top:var(--hairline);
  margin-top:var(--space-7);
  padding:var(--space-5) 0 var(--space-7);
}
.foot .label{margin-right:auto}
.foot a{font-size:15px}

/* --- reveal -------------------------------------------------------------- */
/* One effect, used identically in both places: 300ms each, 150ms apart. */

/* Hidden only when the inline head script has armed it. If anything at all goes
   wrong — no JS, blocked script, CSP — .reveal-armed is never set and the
   content is simply visible. The page must never depend on JS to be readable. */
.reveal-armed .reveal>*{
  opacity:.001;
  transform:translateY(var(--reveal-travel));
  filter:blur(var(--reveal-blur));
  transition:opacity var(--reveal-duration) var(--ease),
             transform var(--reveal-duration) var(--ease),
             filter var(--reveal-duration) var(--ease);
}
.reveal-armed .reveal.is-in>*{opacity:1;transform:none;filter:blur(0)}

@media (prefers-reduced-motion:reduce){
  .reveal>*{transform:none;filter:none;transition:opacity var(--reveal-duration) var(--ease)}
  .row:active{transform:none}
  .glow{animation:none}
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important}
}
