/* ══ 145 PARK — /dan ═════════════════════════════════════════════════════
   The Dan page. This file holds ONLY what this page adds on top of the site's
   shared styles.css: the reel hero, the work grid, the lyric card and the
   lightbox. Everything else — tokens, grid, glow, .wrap, .sec, .eyebrow,
   .rule, .btn, .kv, header, footer, the [data-r] reveal helper and the
   reduced-motion block — comes from styles.css and is NOT repeated here.

   Load order: styles.css, then dan.css.
   ═══════════════════════════════════════════════════════════════════════ */

/* ══ HERO ═══════════════════════════════════════════════════════════════ */
.dhero{
  position:relative;
  min-height:100svh;
  display:flex;align-items:flex-end;
  padding:96px 0 clamp(40px,7vh,84px);
  overflow:hidden;
}
.dhero-media{position:absolute;inset:0;z-index:0;overflow:hidden;background:#000}
.dhero-media img,
.dhero-media iframe{
  position:absolute;top:50%;left:50%;
  transform:translate(-50%,-50%);
  border:0;
}
/* the reel is 16:9 — cover the viewport at any shape, never letterbox */
.dhero-media .fill{
  width:100vw;height:56.25vw;
  min-height:100svh;min-width:177.78svh;
  max-width:none;                 /* beats the shared img{max-width:100%} */
  object-fit:cover;
}
.dhero-media img{opacity:.92}
.dhero-veil{
  position:absolute;inset:0;
  background:
    /* floor — the type sits on near-solid black */
    linear-gradient(to top,rgba(0,0,0,.97) 2%,rgba(0,0,0,.58) 44%,rgba(0,0,0,.50) 100%),
    /* left rail — the name never fights a busy frame */
    linear-gradient(to right,rgba(0,0,0,.74),transparent 62%),
    /* scrim under the fixed header — the nav must read over ANY frame */
    linear-gradient(to bottom,rgba(0,0,0,.74),transparent 170px);
}
.dhero-in{position:relative;z-index:2;width:100%}

.dhero-h{
  margin:18px 0 20px;
  color:var(--t1);
  font-size:clamp(44px,8vw,104px);
  font-weight:300;
  line-height:1.02;
  letter-spacing:-.03em;
}
.dhero-h strong{font-weight:700}
.dhero-line{
  max-width:56ch;color:var(--t2);
  font-size:clamp(16px,1.5vw,20px);line-height:1.55;
}
.dhero-line strong{color:var(--t1);font-weight:600}
.dhero-sub{margin-top:14px;max-width:56ch;color:var(--t4);font-size:15px}

/* scroll cue — one quiet marker running down a hairline */
.cue{
  display:inline-flex;align-items:center;gap:13px;
  margin-top:clamp(26px,5vh,50px);
  color:var(--t5);
  font:700 9.5px/1 var(--ui);letter-spacing:.24em;text-transform:uppercase;
  transition:color .28s var(--ease);
}
.cue:hover,.cue:focus-visible{color:var(--t2)}
.cue-bar{position:relative;width:1px;height:38px;background:var(--line2);overflow:hidden}
.cue-bar::after{
  content:"";position:absolute;inset:0;background:var(--y);
  transform:translateY(-100%);
  animation:cue-drop 2.6s var(--ease) infinite;
}
@keyframes cue-drop{
  0%{transform:translateY(-100%)}
  55%,100%{transform:translateY(100%)}
}

/* ══ WHAT HE DOES ═══════════════════════════════════════════════════════ */
.does{
  display:grid;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--r);overflow:hidden;
  grid-template-columns:repeat(3,minmax(0,1fr));
}
.does > div{background:var(--bg);padding:clamp(20px,2.2vw,30px)}
.does dt{
  color:var(--t1);
  font:600 13px/1.4 var(--ui);letter-spacing:.02em;
  margin-bottom:8px;
}
.does dd{color:var(--t4);font-size:14px;line-height:1.6}
.does .n{
  display:block;color:var(--y);
  font:700 9.5px/1 var(--ui);letter-spacing:.24em;margin-bottom:12px;
}

/* ══ WORK GRID ══════════════════════════════════════════════════════════ */
.wgrid{
  display:grid;
  /* minmax(0,…) not 1fr: a bare 1fr floors at min-content, so one long title
     widens its column and the grid goes ragged (measured: 330/431/352px). */
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:clamp(22px,2.6vw,40px) clamp(18px,2.2vw,32px);
}
.work{
  display:block;width:100%;text-align:left;cursor:pointer;
  border:0;background:none;padding:0;color:inherit;font:inherit;
  /* a stretched <button> vertically CENTRES its own content, which pushed the
     shorter cards' frames down by up to 30px. Sizing to content stops it. */
  align-self:start;
}
.w-frame{
  position:relative;display:block;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r);
  background:#0c0c0c;aspect-ratio:16/9;
}
.w-frame img{
  width:100%;height:100%;object-fit:cover;opacity:.82;
  transition:transform .8s var(--ease),opacity .5s var(--ease);
}
.w-frame::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  border:1px solid var(--y);border-radius:var(--r);
  opacity:0;transition:opacity .38s var(--ease);
}
.w-play{
  position:absolute;left:14px;bottom:14px;z-index:2;
  width:40px;height:40px;border-radius:var(--r);
  display:grid;place-items:center;
  background:rgba(0,0,0,.62);border:1px solid var(--line2);color:var(--t1);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  opacity:0;transform:translate3d(0,6px,0);
  transition:opacity .38s var(--ease),transform .38s var(--ease),
             background .38s var(--ease),color .38s var(--ease),
             border-color .38s var(--ease);
}
.work:hover .w-frame img,
.work:focus-visible .w-frame img{transform:scale(1.045);opacity:1}
.work:hover .w-frame::after,
.work:focus-visible .w-frame::after{opacity:.5}
.work:hover .w-play,
.work:focus-visible .w-play{opacity:1;transform:none}
.work:hover .w-play{background:var(--y);color:#000;border-color:var(--y)}
.work:hover .w-title,
.work:focus-visible .w-title{color:var(--y)}

.w-body{display:block;padding-top:15px}
/* the kicker slot is ALWAYS present, filled or not, so the titles in a row
   line up. line-height and min-height must MATCH or an empty one is 4px short. */
.w-kicker{
  display:block;line-height:1.6;min-height:1.6em;margin-bottom:5px;
  color:var(--t5);
  font:700 9.5px var(--ui);letter-spacing:.22em;text-transform:uppercase;
}
.w-title{
  display:block;color:var(--t1);
  font-size:clamp(16px,1.45vw,19px);font-weight:600;
  line-height:1.25;letter-spacing:-.012em;
  transition:color .3s var(--ease);
}
/* inline flow, NOT flex: with flex the separator leads a wrapped line and the
   block reads as a row of orphaned dots. Inline keeps each "item ·" together. */
.w-meta{
  display:block;margin-top:8px;color:var(--t5);
  font:600 10px/1.9 var(--ui);letter-spacing:.14em;text-transform:uppercase;
}
.w-meta span{white-space:nowrap}
.w-meta span:not(:last-child)::after{content:"·";margin-inline:8px;color:var(--t5)}
.w-meta .m-client{color:var(--t3)}
.w-meta .m-rt{letter-spacing:.1em}
.w-note{
  display:flex;align-items:center;gap:8px;margin-top:9px;
  color:var(--y-dim);
  font:700 10px/1.5 var(--ui);letter-spacing:.16em;text-transform:uppercase;
}
.w-note::before{
  content:"";flex:0 0 auto;width:5px;height:5px;border-radius:1px;background:var(--y);
}

/* ══ LYRIC CARD ═════════════════════════════════════════════════════════
   Press the button and the card RIFFLES — a departure board / tape shuttle —
   through a few real entries and lands on the new one.

   Only the LYRIC LINES move while it riffles. The attribution and the Spotify
   link hold their place at .3 opacity and come back on the landing: three
   lines of different lengths all changing at once reads as flicker, not as a
   shuttle. Set RIFFLE=false at the top of dan.js for a plain cross-fade.     */
.lyric-intro{max-width:46ch;color:var(--t4);font-size:15px;margin-bottom:26px}

.lyric-card{
  position:relative;
  border:1px solid var(--line);border-radius:var(--r);
  background:var(--surf);
  padding:clamp(24px,3.2vw,40px);
  display:grid;gap:28px;align-content:space-between;
  max-width:820px;          /* a cue card, not a banner */
  min-height:250px;         /* holds height between entries, chip or no chip */
}
.lyric-card::before,.lyric-card::after{
  content:"";position:absolute;width:12px;height:12px;pointer-events:none;
  border-color:var(--y-dim);border-style:solid;border-width:0;
}
.lyric-card::before{top:-1px;left:-1px;border-top-width:1px;border-left-width:1px}
.lyric-card::after{bottom:-1px;right:-1px;border-bottom-width:1px;border-right-width:1px}

.lyric-swap{transition:opacity .24s var(--ease),transform .24s var(--ease)}
.lyric-swap.is-out{opacity:0;transform:translate3d(0,-4px,0)}
.lyric-swap.is-in{opacity:0;transform:translate3d(0,4px,0)}

.lyric-quote{
  margin:0;color:var(--t1);
  /* Courier New — Dan named it, and it reads like a cue sheet */
  font-family:"Courier New",Courier,monospace;
  font-size:clamp(17px,2.05vw,26px);line-height:1.58;letter-spacing:-.005em;
}
.lyric-quote .ly{display:block;overflow-wrap:anywhere}

.lyric-foot{
  display:flex;align-items:flex-end;justify-content:space-between;
  gap:22px;flex-wrap:wrap;min-height:58px;
  transition:opacity .22s var(--ease);
}
.lyric-card.is-riffling .lyric-foot{opacity:.3}
.lyric-card.is-riffling .lyric-quote{color:var(--t2)}

.lyric-attr{
  color:var(--t5);
  font:700 10px/1.8 var(--ui);letter-spacing:.20em;text-transform:uppercase;
}
.lyric-attr .a-artist{color:var(--t2)}
.lyric-attr .sep{color:var(--t5);margin-inline:7px}

/* a link only. No Spotify embed: heavy, and it tracks the visitor. */
.spot{
  display:inline-flex;align-items:center;gap:7px;margin-top:9px;
  color:var(--y);
  border:1px solid var(--y-faint);border-radius:var(--r);padding:5px 10px;
  font:700 9.5px/1 var(--ui);letter-spacing:.20em;text-transform:uppercase;
  transition:background .28s var(--ease),color .28s var(--ease),
             border-color .28s var(--ease);
}
.spot svg{flex:0 0 auto}
.spot:hover,.spot:focus-visible{background:var(--y);color:#000;border-color:var(--y)}

/* the shared .btn is only ever used on an <a>, so it never needed to reset a
   native button. On a <button> the UA background (buttonface, rgb(107,107,107))
   shows straight through — hence the appearance reset here. */
.lyric-btn,.lb-close{
  -webkit-appearance:none;appearance:none;background:transparent;
}
.lyric-btn{cursor:pointer;margin-top:0}
.lyric-btn[disabled]{opacity:.45;cursor:default}
.lyric-btn[disabled]:hover{border-color:var(--line2);color:var(--t2);background:transparent}

/* ══ LIGHTBOX ═══════════════════════════════════════════════════════════ */
.lb{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;
  padding:clamp(14px,3.4vw,52px);
  background:rgba(3,3,3,.93);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  opacity:0;visibility:hidden;
  /* visibility flips only AFTER the fade-out, and instantly on the way in, so
     the close button is focusable the moment the dialog opens. */
  transition:opacity .34s var(--ease),visibility 0s linear .34s;
}
.lb.is-open{
  opacity:1;visibility:visible;
  transition:opacity .34s var(--ease),visibility 0s linear 0s;
}
body.lb-lock{overflow:hidden}
.lb-inner{
  width:min(100%,1400px);
  transform:translate3d(0,12px,0) scale(.99);
  transition:transform .42s var(--ease);
}
.lb.is-open .lb-inner{transform:none}
.lb-bar{display:flex;align-items:flex-end;justify-content:space-between;
  gap:20px;margin-bottom:14px}
.lb-kick{
  color:var(--y);
  font:700 9.5px/1 var(--ui);letter-spacing:.22em;text-transform:uppercase;
  margin-bottom:7px;
}
.lb-title{color:var(--t1);font-size:clamp(14px,1.5vw,18px);font-weight:600;
  line-height:1.3;letter-spacing:-.01em}
.lb-close{
  flex:0 0 auto;cursor:pointer;display:inline-flex;align-items:center;gap:9px;
  border:1px solid var(--line2);border-radius:var(--r);
  background:none;padding:10px 15px;color:var(--t3);
  font:700 9.5px/1 var(--ui);letter-spacing:.20em;text-transform:uppercase;
  transition:background .28s var(--ease),color .28s var(--ease),
             border-color .28s var(--ease);
}
.lb-close:hover,.lb-close:focus-visible{background:var(--y);color:#000;border-color:var(--y)}
.lb-stage{
  position:relative;width:100%;aspect-ratio:16/9;overflow:hidden;
  background:#000;border:1px solid var(--line);border-radius:var(--r);
}
.lb-stage iframe{position:absolute;inset:0;width:100%;height:100%;border:0}

/* ══ CLOSE / HAND-OFF ═══════════════════════════════════════════════════ */
.dend{
  border:1px solid var(--line);border-radius:var(--r);background:var(--surf);
  padding:clamp(26px,3.6vw,46px);
}
.dend-h{
  color:var(--t1);font-size:clamp(21px,2.4vw,30px);font-weight:300;
  line-height:1.2;letter-spacing:-.018em;max-width:22ch;margin-bottom:14px;
}
.dend p{color:var(--t4);max-width:52ch;font-size:15.5px}

/* ══ RESPONSIVE ═════════════════════════════════════════════════════════ */
@media (max-width:1040px){
  .wgrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .does{grid-template-columns:repeat(2,minmax(0,1fr))}
  .work{--d:0!important}     /* staggering in pairs reads wrong; keep it calm */
}
@media (max-width:680px){
  .wgrid{grid-template-columns:minmax(0,1fr)}
  .does{grid-template-columns:minmax(0,1fr)}
  .dhero{min-height:92svh}
  .lyric-card{min-height:300px}
  .lyric-foot{flex-direction:column;align-items:stretch}
  .lyric-btn{justify-content:center}
}

/* ══ REDUCED MOTION ═════════════════════════════════════════════════════
   styles.css already collapses the shared reveals. These are this page's own. */
@media (prefers-reduced-motion:reduce){
  .cue-bar::after{animation:none;transform:translateY(0)}
  .w-play{opacity:1;transform:none}
  .w-frame img{transition:none}
  .lyric-swap{transition:none!important}
  .lb,.lb-inner{transition:none!important}
}

/* visually hidden, still announced (the shared styles.css has no helper) */
.vh{
  position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

/* ── dangalway.com = the contact card (2026-11-04) ─────────────────────── */
.dg-card{min-height:calc(100vh - 140px);display:flex;align-items:center;padding-top:clamp(90px,12vh,140px)}
.dg-card .wrap{width:100%}
/* the award marks + lists live in styles.css now (both pages use them) */
