/* ===========================================================================
   vilirobertollila.com

   One typeface (EB Garamond, weights 400 and 500), no italics anywhere, and
   one colour on the whole page: the IMDb yellow. Hierarchy comes from size,
   letterspacing and the grey scale below — never from mixing typefaces.

   A note on letterspacing: CSS puts the gap AFTER each letter, including the
   last one, so centred tracked text sits slightly left of true centre. Every
   tracked element below carries a padding-left equal to its tracking to undo
   this. That is what the `padding-left` lines are doing.
   =========================================================================== */

:root {
  --bg:         #0b0b0a;   /* page background, near-black and slightly warm */
  --panel:      #121110;   /* player card, revealed poster card */
  --ink:        #f4f2ec;   /* primary text — warm bone, never pure white */
  --muted:      #8f8c83;   /* secondary text, labels */
  --dim:        #6b685f;   /* tertiary, footer, counts */
  --faint:      #55534c;   /* copyright line */
  --rule:       #1b1b18;   /* hairline dividers */
  --border:     #292824;   /* card and tile borders */
  --border-lit: #a5a299;   /* active / hover tile border */
  --imdb:       #F5C518;   /* IMDb badge yellow — the only colour on the page */

  --wave-played:   var(--muted);
  --wave-unplayed: #33312c;

  --tile-gap: 10px;
}

/* --- reset ---------------------------------------------------------------- */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'EB Garamond', Garamond, Georgia, 'Times New Roman', serif;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.55;
  font-style: normal;
  -webkit-font-smoothing: antialiased;
}

/* No italics anywhere. This was a design decision, so enforce it. */
i, em, cite, address, dfn, var { font-style: normal; }

h1, h2, p, ol, ul, figure { margin: 0; }
ol, ul { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
/*
  Browsers give <button> a padding of their own — 1px 6px in Chrome. Left in
  place it eats the content box of a small round button, and an icon wider than
  what is left over ends up visibly off-centre. Every button here sets whatever
  padding it actually wants.
*/
button { font: inherit; color: inherit; padding: 0; }

a { color: inherit; text-decoration: none; }

/* Visible focus for anyone using a keyboard. */
:focus-visible {
  outline: 1px solid var(--border-lit);
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
}
.skip:focus {
  left: 50%;
  top: 8px;
  transform: translateX(-50%);
  z-index: 10;
  background: var(--ink);
  color: var(--bg);
  padding: 8px 14px;
  border-radius: 3px;
}

.wrap {
  max-width: 960px;
  margin: 0 auto;
  padding: 0 24px;
}

/* --- shared pieces -------------------------------------------------------- */

/* ORCHESTRATION · MUSIC DEPARTMENT, CONTACT */
.section-label {
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.34em;
  padding-left: 0.34em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
}

/* The CONTACT ↓ button, and SHOW ALL on a phone. */
.pill {
  display: inline-block;
  background: none;
  border: 1px solid #4a473f;
  border-radius: 20px;
  padding: 8px 17px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.22em;
  padding-right: calc(17px - 0.22em);
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  transition: border-color 140ms linear, color 140ms linear;
}
.pill:hover,
.pill:focus-visible {
  border-color: var(--border-lit);
  color: var(--ink);
}

/* ===========================================================================
   Header
   =========================================================================== */

.header {
  padding: 72px 0 56px;
  text-align: center;
}

/*
  The name and the tagline are one block and scale together. Both sizes below
  are the original design values plus 30%: 33px -> 43px and 13px -> 17px. The
  letterspacing is in em, so the tracking grows with the type on its own and the
  proportions stay exactly as approved.
*/
.logo {
  font-size: 43px;
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: 0.24em;
  padding-left: 0.24em;
  text-transform: uppercase;
  color: var(--ink);
}
.logo picture { display: block; }
.logo img {
  margin: 0 auto;
  width: 100%;
  max-width: 546px;
  padding-left: 0; /* an SVG logotype is already optically centred */
}

/*
  The two halves of the name. On a wide window they sit side by side and read as
  one line; below the breakpoint further down they each become their own line,
  matching the commissioned two-line logotype:

      VILI ROBERT
         OLLILA
*/
.logo-line {
  display: inline;
  /* Each half is one line or nothing. Without this a very narrow window can
     break VILI ROBERT again into VILI / ROBERT, giving three lines instead of
     the two the logotype is drawn as. */
  white-space: nowrap;
}

.tagline {
  margin-top: 21px;
  font-size: 17px;
  font-weight: 500;
  letter-spacing: 0.38em;
  padding-left: 0.38em;
  text-transform: uppercase;
  color: var(--muted);
}

.links {
  margin-top: 30px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 18px;
}

/* IMDb badge — their official logo. The only colour on the page. The height is
   what sets the size; the width follows the logo's own proportions. */
.imdb {
  display: block;
  line-height: 0;
}
.imdb img { display: block; height: 22px; width: auto; }
.imdb:hover, .imdb:focus-visible { opacity: 0.85; }

/* Instagram stays monochrome on purpose. */
.instagram {
  display: grid;
  place-items: center;
  width: 44px;   /* 44px tap target, though the mark itself is 20px */
  height: 44px;
  color: var(--muted);
  transition: color 140ms linear;
}
.instagram:hover, .instagram:focus-visible { color: var(--ink); }
.instagram svg { width: 20px; height: 20px; }

/* ===========================================================================
   The music
   =========================================================================== */

.player {
  padding-bottom: 64px;
}

.player-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 18px 20px 14px;
}

.player-head {
  display: flex;
  align-items: center;
  gap: 14px;
}
.player-head[hidden] { display: none; }

.playpause {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: -6px -8px -6px -6px; /* keeps the 44px target without pushing the layout */
  background: none;
  border: 0;
  border-radius: 50%;
  color: var(--ink);
  cursor: pointer;
}
.playpause svg { width: 26px; height: 26px; fill: currentColor; }
.playpause .icon-pause { display: none; }
.playpause[data-playing='true'] .icon-play { display: none; }
.playpause[data-playing='true'] .icon-pause { display: block; }
.playpause:disabled { color: var(--faint); cursor: default; }

.player-now {
  min-width: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.player-title {
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--ink);
}

.player-descriptor {
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--dim);
}

.player-time {
  flex: none;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--dim);
}

.waveform {
  margin-top: 14px;
  min-height: 64px;
  cursor: pointer;
}
.waveform[hidden] { display: none; }

.player-empty {
  padding: 14px 0;
  text-align: center;
  color: var(--dim);
}

/* --- the track list ------------------------------------------------------- */

.tracklist { margin-top: 8px; }

.track {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  min-height: 44px;
  padding: 11px 2px;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  cursor: pointer;
  color: var(--muted);
  transition: color 140ms linear;
}
.tracklist li:last-child .track { border-bottom: 0; }

.track:hover .track-title,
.track:focus-visible .track-title { color: var(--ink); }

.track[aria-current='true'] .track-title { color: var(--ink); }

.track-title {
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color 140ms linear;
}

.track-descriptor {
  flex: none;
  font-size: 14px;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--dim);
  text-align: right;
}

/* ===========================================================================
   The poster wall
   =========================================================================== */

.wall-section {
  padding: 56px 0 64px;
  border-top: 1px solid var(--rule);
  text-align: center;
}

.wall {
  margin-top: 34px;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: var(--tile-gap);
}

.tile {
  position: relative;
  aspect-ratio: 2 / 3;
  cursor: pointer;
  perspective: 900px;
  -webkit-tap-highlight-color: transparent;
}

.tile-inner {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transition: transform 420ms cubic-bezier(0.4, 0.1, 0.2, 1);
}
.tile[data-revealed='true'] .tile-inner { transform: rotateY(180deg); }

.tile-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border: 1px solid var(--border);
  border-radius: 2px;
  overflow: hidden;
}

.tile-front { background: #000; }
.tile-front img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.tile-back {
  transform: rotateY(180deg);
  background: var(--panel);
  border-color: var(--border-lit);
  /* No padding here — the composer panel at the foot runs to the card edges.
     The padding lives on .tile-head and .tile-composer instead. */
  padding: 0;
  display: flex;
  flex-direction: column;
  text-align: left;
  overflow: hidden;
}

/* The film: title, year, role, award. Always at the top of the card. */
.tile-head {
  padding: 11px 11px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  /*
    If a card ever holds more text than it has room for, this is the part that
    gives way — never the composer panel below. A clipped last word of an award
    line is a small loss; a composer name pushed off the bottom of the card is
    the whole point of the card going missing.
  */
  flex: 0 1 auto;
  min-height: 0;
  overflow: hidden;
}

/* The excerpt and the composer, pushed to the foot of the card and never
   compressed. */
.tile-foot {
  margin-top: auto;
  flex: none;
}

.tile-title {
  font-size: 12.5px;
  font-weight: 500;
  letter-spacing: 0.06em;
  line-height: 1.32;
  text-transform: uppercase;
  color: var(--ink);
}

.tile-english {
  font-size: 12px;
  font-weight: 400;
  line-height: 1.35;
  color: var(--dim);
  margin-top: -4px;
}

.tile-meta {
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--muted);
}

.tile-award {
  font-size: 12px;
  font-weight: 400;
  line-height: 1.4;
  color: var(--dim);
}

/*
  The composer panel.

  Inverted — bone ground, near-black type — which is the same reversal the
  contact form uses, so no new colour enters the page. It is the one panel on
  the card that is not grey-on-black, and that is deliberate: on an
  orchestration credit the composer is the name that places the work.
*/
.tile-composer {
  background: var(--ink);
  color: #1a1a18;
  padding: 8px 11px 9px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.tile-composer-label {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #6f6c64;
}

.tile-composer-name {
  font-size: 14.5px;
  font-weight: 500;
  letter-spacing: 0.01em;
  line-height: 1.25;
  color: #1a1a18;
}

/* The excerpts on a revealed tile, resting just above the composer panel. */
.tile-clips {
  margin: 0 11px 9px;
}

/* Labelled excerpts: one row each, label beside the button. */
.tile-clips--labelled {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.tile-clip {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.tile-clip-label {
  font-size: 11.5px;
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: 0.01em;
  color: var(--muted);
  /* A long cue name shortens rather than pushing the row out of the card. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The play button itself. Stays tappable on its own. */
.tile-play {
  flex: none;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  background: none;
  border: 1px solid var(--border-lit);
  border-radius: 50%;
  color: var(--ink);
  cursor: pointer;
}

/* Smaller only when there are several rows to fit. A single labelled excerpt
   keeps the full-size button, since it has the room. */
.tile-clips--multi .tile-play { width: 26px; height: 26px; }
.tile-clips--multi .tile-play svg { width: 14px; height: 14px; }
.tile-play svg { width: 17px; height: 17px; fill: currentColor; }
.tile-play .icon-pause { display: none; }
.tile-play[data-playing='true'] .icon-play { display: none; }
.tile-play[data-playing='true'] .icon-pause { display: block; }

.wall-showall {
  margin-top: 26px;
  display: none; /* only ever shown on a phone — see the media query */
}

/*
  The second wall: theatre, concerts, sound branding. One row of five, same
  2:3 tiles as the films. It reads as a coda to the wall above rather than a
  second exhibition, so it is tighter above and below and carries no closing
  line of its own.
*/
.projects-section { padding: 48px 0 56px; }
.projects-section[hidden] { display: none; }

.wall-closing {
  margin-top: 34px;
  color: var(--dim);
  text-align: center;
}
.wall-closing a {
  color: var(--muted);
  border-bottom: 1px solid var(--rule);
}
.wall-closing a:hover,
.wall-closing a:focus-visible { color: var(--ink); }

/* ===========================================================================
   Contact
   =========================================================================== */

.contact-section {
  padding: 56px 0 64px;
  border-top: 1px solid var(--rule);
  text-align: center;
}

.contact-intro {
  margin-top: 18px;
  color: var(--dim);
}

/*
  The fields are light on the black page on purpose: they read as "type here"
  and give the page its single call to action.
*/
.contact-form {
  max-width: 400px;
  margin: 30px auto 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: left;
}

.honeypot { position: absolute; left: -9999px; }

.field { display: block; }
.field-label {
  position: absolute;
  left: -9999px; /* the placeholder carries the label visually */
}

.contact-form input,
.contact-form textarea {
  width: 100%;
  min-height: 44px;
  background: var(--ink);
  color: #1a1a18;
  border: 1px solid var(--ink);
  border-radius: 3px;
  padding: 11px 12px;
  font-family: inherit;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.45;
}
.contact-form textarea { resize: vertical; }

.contact-form ::placeholder {
  color: #6f6c64;
  opacity: 1;
}

.contact-form input:focus-visible,
.contact-form textarea:focus-visible {
  outline: 1px solid var(--border-lit);
  outline-offset: 2px;
}

/* A field the browser has marked invalid after a failed send. */
.contact-form [aria-invalid='true'] {
  border-color: #b8b3a4;
  box-shadow: inset 0 0 0 1px #b8b3a4;
}

.send {
  align-self: flex-start;
  margin-top: 6px;
  min-height: 44px;
  background: var(--ink);
  color: #12110f;
  border: 0;
  border-radius: 20px;
  padding: 11px 26px;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.2em;
  padding-right: calc(26px - 0.2em);
  text-transform: uppercase;
  cursor: pointer;
  transition: opacity 140ms linear;
}
.send:hover, .send:focus-visible { opacity: 0.88; }
.send:disabled { opacity: 0.5; cursor: default; }

.form-note {
  margin-top: 4px;
  color: var(--muted);
  line-height: 1.5;
}

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

.footer {
  padding: 34px 0 46px;
  border-top: 1px solid var(--rule);
  text-align: center;
}
.footer p {
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.14em;
  padding-left: 0.14em;
  text-transform: uppercase;
  color: var(--faint);
}

/* ===========================================================================
   Narrower screens
   =========================================================================== */

/* Four across, then three, before dropping to the phone layout. */
@media (max-width: 860px) {
  .wall { grid-template-columns: repeat(4, 1fr); }
}

@media (max-width: 680px) {
  .wall { grid-template-columns: repeat(3, 1fr); }
  .tile-title { font-size: 12px; }

  /*
    From here down the name is set on two lines — the commissioned stacked
    logotype, or the two spans standing in for it. This is the breakpoint that
    STACKED_LOGO_BELOW in app.js has to match.

    Because stacking is now what we want rather than something to avoid, the
    type does not have to shrink to keep the name on one line. It stays at the
    full 43px.
  */
  .logo-line { display: block; }
  .logo img { max-width: 340px; }
  .logo { line-height: 1.28; }
}

/* --- phones -------------------------------------------------------------- */

@media (max-width: 540px) {
  .wrap { padding: 0 18px; }

  .header { padding: 52px 0 42px; }

  /*
    Still two lines, sized to fit a phone. 36px is the intended size and what
    every normal phone gets. Below roughly 360px wide the size eases down with
    the window so the longer line, VILI ROBERT, always fits — right down to a
    folded phone at 280px. Working: that line is about 8.7x the font size wide,
    plus the 0.24em tracking padding, inside the window less 36px of page
    padding. 10.8vw - 4px stays under that at every width, with room to spare.
  */
  .logo { font-size: min(36px, calc(10.8vw - 4px)); }
  .logo img { max-width: min(280px, 84vw); }
  .tagline {
    font-size: min(13px, calc(3.55vw - 0.5px));
    letter-spacing: 0.3em;
    padding-left: 0.3em;
  }

  .section-label { font-size: 12px; letter-spacing: 0.28em; padding-left: 0.28em; }

  .player-card { padding: 15px 15px 12px; }
  .player-head { gap: 11px; }
  .player-title { font-size: 15px; }
  .player-descriptor { font-size: 13px; }
  .player-time { font-size: 12px; }

  /* The track list stacks so long titles never collide with descriptors. */
  .track { flex-direction: column; align-items: flex-start; gap: 2px; }
  .track-title { font-size: 15px; }
  .track-descriptor { text-align: left; font-size: 13px; }

  /* One poster per screen width, full-bleed inside the page padding. */
  .wall { grid-template-columns: 1fr; gap: 16px; }

  /* Only the first 15 films until SHOW ALL is pressed — 65 full-width posters
     is otherwise an unreasonable scroll. */
  .wall--films.wall--collapsed .tile:nth-child(n + 16) { display: none; }

  /* The second wall is a coda, so it shows one and offers SHOW MORE. */
  .wall--projects.wall--collapsed .tile:nth-child(n + 2) { display: none; }

  .wall-showall { display: inline-block; }

  /* The film stays at the top of the card and the composer panel sits at the
     foot of it, so a full-width tile reads top to bottom with no dead middle. */
  .tile-head { padding: 20px 18px; gap: 10px; }
  .tile-title { font-size: 15px; letter-spacing: 0.06em; }
  .tile-english, .tile-meta, .tile-award { font-size: 14px; }

  .tile-composer { padding: 14px 18px 15px; gap: 2px; }
  .tile-composer-label { font-size: 11px; }
  .tile-composer-name { font-size: 19px; }

  .tile-clips { margin: 0 18px 16px; }
  .tile-clips--labelled { gap: 10px; }
  .tile-clip-label { font-size: 15px; }

  /* Full 44px tap targets on a phone, labelled or not. */
  .tile-play,
  .tile-clips--multi .tile-play {
    width: 44px;
    height: 44px;
  }
  .tile-play svg,
  .tile-clips--multi .tile-play svg { width: 20px; height: 20px; }

  .send { align-self: stretch; text-align: center; }
}


/* ===========================================================================
   Anyone who has asked their device to reduce motion gets an instant swap
   instead of the flip.
   =========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
  .tile { perspective: none; }
  .tile-inner { transform: none !important; }
  .tile-face { backface-visibility: visible; -webkit-backface-visibility: visible; }
  .tile-back { transform: none; display: none; }
  .tile[data-revealed='true'] .tile-front { display: none; }
  .tile[data-revealed='true'] .tile-back { display: flex; }
}
