/* ============================================================================
   Viviane Dias Photography — V3
   ONE stylesheet. Every class used in the HTML exists here; nothing else does.
   Black & white is the default palette; colour, dark and language are choices
   the visitor makes and the site remembers.
   ========================================================================== */

/* ---------- 1. tokens ---------------------------------------------------- */
:root{
  --serif:"Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans:"Jost", system-ui, -apple-system, "Segoe UI", sans-serif;

  --paper:#F7F4EF;
  --paper-2:#F1EDE6;
  --mat:#FFFFFF;
  --ink:#1A1A1A;
  --ink-2:#4A4640;
  /* ink-3 was #7B7469: 3.96:1 on the sand ground, under the 4.5 floor on 66 of
     the 67 light-theme nodes that failed it. Same hue, one step darker. */
  --ink-3:#6F685E;
  --line:#E2DCD2;
  --accent:#3F5A5E;
  --accent-2:#B08B4F;
  --sea:#EDE9E1;
  --land:#F7F4EF;
  --coast:#B9B2A6;
  --shadow:0 1px 2px rgba(26,26,26,.04), 0 10px 34px rgba(26,26,26,.07);

  /* type scale — five rendered sizes, and nothing below 13px (the pipeline
     floor; the caption tier used to sit at 12px).
     micro 13 · body 17 · lead 21 · head 25.6 · display 41.6.
     There is no 15px tier any more: running copy that used to sit on it (the
     step paragraphs, the door and album lines, the contact lines, the form
     note, the map story) is body copy and now reads at 17px everywhere. */
  --t-display:clamp(2.6rem, 6vw, 4.2rem);
  --t-head:clamp(1.6rem, 3.4vw, 2.4rem);
  --t-lead:1.3125rem;
  --t-body:1.0625rem;
  --t-micro:.8125rem;

  /* spacing rhythm — one scale */
  --gap-s:clamp(1.6rem, 3vw, 2.4rem);
  --gap:clamp(3.2rem, 6vw, 5rem);
  --gap-l:clamp(5rem, 10vw, 8rem);
  --pad:clamp(1.15rem, 4vw, 2.5rem);
  --measure:34rem;

  --ease:cubic-bezier(.22,.61,.36,1);
}
html[data-theme="dark"]{
  --paper:#121110;
  --paper-2:#191714;
  --mat:#221F1B;
  --ink:#F1ECE3;
  --ink-2:#C7C0B5;
  --ink-3:#948C81;
  --line:#302D28;
  --accent:#8FB3B8;
  --accent-2:#D8B278;
  --sea:#0B0A09;
  --land:#191714;
  --coast:#3B3831;
  --shadow:0 1px 2px rgba(0,0,0,.4), 0 12px 38px rgba(0,0,0,.45);
}

*,*::before,*::after{ box-sizing:border-box }
html{ -webkit-text-size-adjust:100% }
body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:var(--sans); font-size:var(--t-body); font-weight:300; line-height:1.62;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img,video{ max-width:100%; display:block }
a{ color:inherit }
button{ font:inherit; color:inherit }
h1,h2,h3{ font-family:var(--serif); font-weight:400; letter-spacing:-.005em; margin:0 }
h1{ font-size:var(--t-display); line-height:1.06 }
h2{ font-size:var(--t-head); line-height:1.14 }
h3{ font-size:var(--t-lead); line-height:1.24 }
p{ margin:0 0 1.05em }
p:last-child{ margin-bottom:0 }

/* black & white is the default; the colour toggle simply lifts the filter */
html[data-palette="bw"] img,
html[data-palette="bw"] video,
html[data-palette="bw"] .film__still{
  filter:grayscale(1) contrast(1.03);
}

.wrap{ width:min(1180px, 100% - var(--pad)*2); margin-inline:auto }
.wrap--narrow{ width:min(760px, 100% - var(--pad)*2) }
.lead{ font-size:var(--t-lead); line-height:1.55; color:var(--ink-2); max-width:var(--measure) }
.eyebrow{
  font-size:var(--t-micro); letter-spacing:.24em; text-transform:uppercase;
  color:var(--ink-3); font-weight:400; margin:0 0 .9rem;
}
.skip{
  position:absolute; left:-9999px; top:0; z-index:200; background:var(--mat);
  padding:.7rem 1.1rem; border:1px solid var(--line);
}
.skip:focus{ left:.6rem; top:.6rem }
:focus-visible{ outline:2px solid var(--accent); outline-offset:3px }

/* ---------- 2. masthead + nav ------------------------------------------- */
.masthead{
  position:sticky; top:0; z-index:60; background:var(--paper);
  border-bottom:1px solid var(--line);
}
.masthead__inner{
  width:min(1180px, 100% - var(--pad)*2); margin-inline:auto;
  display:flex; align-items:center; gap:1rem; padding:.85rem 0 .7rem;
}
.wordmark{
  font-family:var(--serif); font-size:var(--t-lead); letter-spacing:.02em;
  text-decoration:none; line-height:1.05; display:flex; flex-direction:column;
  margin-inline:auto;
}
.wordmark span{
  font-family:var(--sans); font-size:var(--t-micro); letter-spacing:.24em;
  text-transform:uppercase; color:var(--ink-3); margin-top:.22rem;
}
.masthead__inner > .wordmark{ margin-left:0; margin-right:auto }

.nav-btn{
  display:none; background:none; border:0; padding:.5rem; margin-left:-.5rem; cursor:pointer;
}
.utility{ display:flex; align-items:center; gap:.4rem }
.ctrl{
  font-family:var(--sans); font-size:var(--t-micro); font-weight:400;
  letter-spacing:.17em; text-transform:uppercase;
  background:none; border:1px solid var(--line); border-radius:999px;
  padding:.5rem .85rem; cursor:pointer; text-decoration:none; color:var(--ink-2);
  display:inline-flex; align-items:center; gap:.42rem; white-space:nowrap;
  transition:color .25s var(--ease), border-color .25s var(--ease);
}
.ctrl:hover{ color:var(--ink); border-color:var(--ink-3) }
.ctrl--cta{ border-color:var(--ink-3); color:var(--ink) }
.ctrl .swatch{
  width:11px; height:11px; border-radius:50%; border:1px solid var(--ink-3);
  background:linear-gradient(135deg, #1a1a1a 0 50%, #b08b4f 50% 100%);
}
html[data-palette="color"] .ctrl .swatch{ background:#1a1a1a }
.ctrl .dot{
  width:11px; height:11px; border-radius:50%; border:1px solid var(--ink-3);
  background:linear-gradient(90deg, var(--ink) 0 50%, transparent 50% 100%);
}
.u-short{ display:none }

.lang{ position:relative }
.lang__list{
  position:absolute; right:0; top:calc(100% + .4rem); min-width:12.5rem;
  background:var(--mat); border:1px solid var(--line); border-radius:.6rem;
  box-shadow:var(--shadow); padding:.3rem; display:none; z-index:70;
}
.lang.is-open .lang__list{ display:block }
.lang__list button{
  display:flex; width:100%; gap:.6rem; align-items:baseline; background:none; border:0;
  text-align:left; padding:.55rem .7rem; cursor:pointer; border-radius:.4rem;
  font-size:var(--t-body); color:var(--ink-2);
}
.lang__list button:hover{ background:var(--paper-2); color:var(--ink) }
.lang__list .code{
  font-size:var(--t-micro); letter-spacing:.16em; text-transform:uppercase; color:var(--ink-3);
  min-width:3.6rem;
}
.lang__list button[aria-current="true"]{ color:var(--ink) }

.navbar{ border-top:1px solid var(--line) }
.navbar__inner{
  width:min(1180px, 100% - var(--pad)*2); margin-inline:auto;
  display:flex; justify-content:center; gap:clamp(1rem, 3vw, 2.4rem); padding:.7rem 0;
  flex-wrap:wrap;
}
.navbar__inner a{
  font-size:var(--t-micro); letter-spacing:.2em; text-transform:uppercase;
  text-decoration:none; color:var(--ink-2); padding:.2rem 0;
  border-bottom:1px solid transparent; transition:color .25s var(--ease), border-color .25s var(--ease);
  display:inline-flex; align-items:center; gap:.4rem;
}
.navbar__inner a:hover{ color:var(--ink) }
.navbar__inner a[aria-current="page"]{ color:var(--ink); border-bottom-color:var(--ink-3) }
.paw{ flex:none }

/* drawer (mobile) */
.drawer{
  position:fixed; inset:0 auto 0 0; width:min(20rem, 84vw); background:var(--paper);
  border-right:1px solid var(--line); z-index:90; padding:var(--pad);
  transform:translateX(-102%); transition:transform .4s var(--ease);
  display:flex; flex-direction:column; gap:.15rem; overflow-y:auto;
}
.drawer.is-open{ transform:none }
.drawer__top{ display:flex; justify-content:space-between; align-items:center; margin-bottom:1.4rem }
.drawer a{
  font-family:var(--serif); font-size:var(--t-head); text-decoration:none; padding:.5rem 0;
  border-bottom:1px solid var(--line); display:flex; align-items:center; gap:.6rem;
}
.drawer a:last-of-type{ border-bottom:0 }
/* the action, on the phone. Sits at the end of the menu, above the languages,
   and opts out of the drawer's link rules so it reads as a button. */
.drawer__cta{ margin-top:1.6rem; align-self:flex-start; border-bottom:1px solid var(--ink-3) !important;
  padding:.85rem 1.7rem !important; font-size:var(--t-micro) !important; text-transform:uppercase }
.drawer__foot{ margin-top:auto; padding-top:1.6rem; display:flex; flex-wrap:wrap; gap:.4rem }
.scrim{
  position:fixed; inset:0; background:rgba(10,9,8,.42); z-index:80; opacity:0;
  pointer-events:none; transition:opacity .4s var(--ease);
}
.scrim.is-on{ opacity:1; pointer-events:auto }

/* ---------- 3. reveal ---------------------------------------------------- */
.reveal{ opacity:0; filter:blur(9px); transform:translateY(7px);
  transition:opacity 1.25s var(--ease), filter 1.25s var(--ease), transform 1.25s var(--ease) }
.reveal.is-in{ opacity:1; filter:blur(0); transform:none }
.reveal-d1{ transition-delay:.16s }
.reveal-d2{ transition-delay:.32s }
.reveal-d3{ transition-delay:.48s }

/* ---------- 4. the film -------------------------------------------------- */
.film{ position:relative; background:#0b0a09 }
.film__stage{
  /* The height follows the film, not a fixed cap. 56.25vw is nine sixteenths of
     the width, so on most windows this box IS 16:9 and object-fit:cover has
     nothing to throw away. The 92vh keeps the hero from swallowing the screen on
     a very wide monitor; that is the only case where any crop is left. */
  position:relative; height:min(92vh, 56.25vw); min-height:31rem;
  /* A window far wider than it is tall is where heads used to go: the height
     runs out of viewport and cover eats the difference. Capping the width in vh
     caps the SHAPE of the box — 178vh against a 92vh height is a ratio of 1.93,
     the same one the tall screens already sit at — so the crop can never grow
     past it. On an ultrawide the film is centred on the film's own black. */
  max-width:178vh; margin-inline:auto;
  overflow:hidden; display:grid; place-items:center;
}
.film__video, .film__still{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  /* When there is anything to crop, take it off the ground rather than off the
     heads: faces sit in the upper half of every frame in this film. */
  object-position:50% 38%;
}
/* .film__still is the CLOSING frame, and it sits after the video in the DOM.
   It used to be painted over the video for the entire run — QA 2026-09-02
   measured a mean pixel diff of 0.01 between frames 4 seconds apart, against
   104.28 with the still hidden: the film was rendering and nobody could see it.
   It now appears only once the film has ended, or when there is no film to
   play at all. Before playback what shows is the video's own poster, which is
   the OPENING frame. */
.film__still{
  background-size:cover; background-position:center 34%;
  opacity:0; transition:opacity .6s var(--ease);
}
.film.is-ended .film__still{ opacity:1 }
.film--nofilm .film__still{ opacity:1; transition:none }
.film__video{ opacity:1 }
.film__grain{
  position:absolute; inset:0; background-image:url("../textures/film-grain-1024.png?v=v5-1");
  background-size:340px; opacity:.16; mix-blend-mode:overlay; pointer-events:none;
}
/* Two scrims, and a reason for each. The film renders its photographs inside a
   white matte, so white type over the middle of a bright frame is unreadable
   without help: a soft centre wash carries the words, and a bottom band carries
   the controls and the scroll cue. Neither one darkens the photograph itself. */
/* V4: the film shows every photograph whole, so the old wash across the middle
   of the frame would now sit on the photograph itself. The words moved into the
   left band instead — blurred backdrop on the upright frames, empty field or
   trees on the four wide ones — and the wash moved with them. */
.film__vignette{
  position:absolute; inset:0; pointer-events:none;
  background:
    radial-gradient(44% 66% at 19% 50%, rgba(8,7,6,.66) 0%, rgba(8,7,6,.32) 56%, transparent 100%),
    linear-gradient(to top, rgba(8,7,6,.52) 0%, rgba(8,7,6,.16) 17%, transparent 32%),
    radial-gradient(128% 98% at 50% 42%, transparent 44%, rgba(8,7,6,.46) 100%);
}
/* the text layer covers the whole stage now, so a beat can be placed against
   the FRAME (left band on a wide screen, under the photograph on a phone)
   instead of against a 44rem box floating in the middle of it. */
.film__text{
  position:absolute; inset:0; z-index:3; color:#F6F2EA;
  max-width:none; padding:0; pointer-events:none;
}
.film__beat{
  position:absolute; left:clamp(1.4rem, 4.5vw, 4rem); top:50%; transform:translateY(-50%);
  width:min(20rem, 34vw); text-align:left; text-wrap:balance;
  font-family:var(--serif); font-size:clamp(1.5rem, 2.6vw, 2.5rem); line-height:1.18;
  margin:0; opacity:0; filter:blur(12px);
  transition:opacity 1.1s var(--ease), filter 1.1s var(--ease);
  text-shadow:0 1px 3px rgba(0,0,0,.6), 0 2px 28px rgba(0,0,0,.8);
}
.film__beat.is-on{ opacity:1; filter:blur(0) }
/* The closing line is longer than the fourteen before it and needs a wider,
   quieter measure; the signature that follows carries nothing else. */
.film__beat--long{ width:min(26rem, 42vw); font-size:clamp(1.35rem, 2.1vw, 1.95rem); line-height:1.28 }
.film__sig{
  font-family:var(--serif); font-style:italic; font-weight:300;
  font-size:clamp(2rem, 3.6vw, 3rem); letter-spacing:.01em; line-height:1;
}
.film__tools{ position:absolute; z-index:4; left:var(--pad); bottom:var(--pad); display:flex; gap:.4rem }
.film__ctrl{
  font-family:var(--sans); font-size:var(--t-micro); letter-spacing:.17em; text-transform:uppercase;
  background:rgba(12,11,10,.42); color:#F6F2EA; border:1px solid rgba(246,242,234,.32);
  border-radius:999px; padding:.48rem .85rem; cursor:pointer; backdrop-filter:blur(6px);
  display:inline-flex; align-items:center; gap:.42rem;
}
.film__ctrl.is-on{ border-color:rgba(246,242,234,.8) }
/* the mark follows the word. At the end frame the button used to read "Play"
   over a pause glyph (QA r2, 2026-09-02). */
.film__glyph{ display:block }
.film__ctrl .film__glyph--play{ display:none }
.film__ctrl.is-play .film__glyph--pause{ display:none }
.film__ctrl.is-play .film__glyph--play{ display:block }
.film__replay{
  position:absolute; z-index:5; left:50%; bottom:calc(var(--pad) + 3.2rem);
  transform:translateX(-50%);
  font-family:var(--sans); font-size:var(--t-micro); letter-spacing:.2em; text-transform:uppercase;
  background:rgba(12,11,10,.42); color:#F6F2EA; border:1px solid rgba(246,242,234,.42);
  border-radius:999px; padding:.62rem 1.3rem; cursor:pointer; backdrop-filter:blur(6px);
  display:inline-flex; align-items:center; gap:.55rem;
}
.film__replay[hidden]{ display:none }
.film__scroll{
  position:absolute; z-index:4; right:var(--pad); bottom:var(--pad);
  color:#fff; text-shadow:0 1px 10px rgba(0,0,0,.9);
  text-decoration:none; display:flex; flex-direction:column;
  align-items:center; gap:.45rem;
  font-size:var(--t-micro); letter-spacing:.22em; text-transform:uppercase;
  /* it sits over the photograph, where the bare text measured 2.37:1. The
     hard-edged plate that fixed it read as a dark pill stuck on the frame
     (Alex, 2026-09-02). The contrast now comes from a soft wash with no edge
     and no border: the corner darkens, the badge disappears. */
  padding:.6rem .8rem .5rem; isolation:isolate;
}
.film__scroll::before{
  content:""; position:absolute; z-index:-1; inset:-70% -85%;
  background:radial-gradient(closest-side, rgba(8,7,6,.72) 0%, rgba(8,7,6,.42) 52%, transparent 100%);
  pointer-events:none;
}
.film__scroll svg{ animation:nudge 2.8s var(--ease) infinite }
@keyframes nudge{ 0%,100%{ transform:translateY(0); opacity:.7 } 50%{ transform:translateY(5px); opacity:1 } }

/* ---------- 5. home sections -------------------------------------------- */
.sec{ padding:var(--gap-l) 0 }
.sec--tight{ padding:var(--gap) 0 }
.sec--mat{ background:var(--paper-2) }

.hi__grid{ display:grid; grid-template-columns:minmax(0,.86fr) minmax(0,1fr); gap:clamp(2rem,5vw,4.5rem); align-items:center }
.plate{ margin:0; background:var(--mat); padding:.7rem; box-shadow:var(--shadow) }
/* about, wide screens: the story on the left, the photograph on the right, one
   band across the column. A photograph with a single caption line beside it was
   the version Alex rejected — the left half now carries real text. */
.plate__inner{ overflow:hidden; background:var(--paper-2) }
.plate img{ width:100%; height:auto }
.figcap{
  font-size:var(--t-micro); letter-spacing:.06em; color:var(--ink-3); margin:.7rem .1rem 0; line-height:1.45;
}

/* three voices, one per segment. Three quotes at the old single-quote size
   would shout; the set is set smaller and columnar, so the section reads as
   evidence rather than as three headlines stacked. */
.voice .eyebrow{ text-align:center }
.voice__set{
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr));
  gap:clamp(1.6rem,3.4vw,3rem); margin-top:var(--gap-s); align-items:start;
}
.voice__q{ margin:0; border-top:1px solid var(--line); padding-top:1.3rem }
.voice__q p{
  font-family:var(--serif); font-size:clamp(1.12rem,1.55vw,1.36rem); line-height:1.46; color:var(--ink);
  margin:0; text-wrap:pretty;
}
.voice__q cite{
  display:block; font-style:normal; font-family:var(--sans); font-size:var(--t-micro);
  letter-spacing:.22em; text-transform:uppercase; color:var(--ink-3); margin-top:1.1rem;
}

.doors{ display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:clamp(.9rem,2vw,1.6rem); align-items:start }
.door{ text-decoration:none; display:block }
.door__frame{ display:block; overflow:hidden; background:var(--paper-2); aspect-ratio:3/4 }
.door__frame img{
  width:100%; height:100%; object-fit:cover;
  transition:transform 1.1s var(--ease);
}
.door:hover .door__frame img{ transform:scale(1.045) }
.door__name{
  font-family:var(--serif); font-size:var(--t-lead); margin:.85rem 0 .2rem; display:flex;
  align-items:center; gap:.5rem; line-height:1.15;
}
.door__line{ display:block; font-size:var(--t-body); color:var(--ink-3); line-height:1.6; margin:0 }

/* ---------- V4: the notes (Quem me ensina a olhar) ---------------------- */
.notes{ display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:clamp(1.1rem,2.4vw,2.1rem) }
.note{ text-decoration:none; display:block }
.note__frame{ display:block; overflow:hidden; background:var(--paper-2); aspect-ratio:4/3 }
.note__frame img{ width:100%; height:100%; object-fit:cover; transition:transform 1.1s var(--ease) }
.note:hover .note__frame img{ transform:scale(1.04) }
.note__date{
  display:block; margin:.85rem 0 .25rem; font-family:var(--sans);
  font-size:var(--t-micro); letter-spacing:.2em; color:var(--ink-3);
}
.note__title{ display:block; font-family:var(--serif); font-size:var(--t-lead); line-height:1.2; margin-bottom:.35rem }
.note__line{ display:block; font-size:var(--t-body); color:var(--ink-3); line-height:1.6 }

/* one note, read at length */
.wrap--reading{ width:min(940px, 100% - var(--pad)*2); margin-inline:auto }
.post{
  display:grid; grid-template-columns:minmax(0,.72fr) minmax(0,1fr);
  gap:clamp(1.6rem,4vw,3.4rem); align-items:start;
  padding:clamp(2rem,5vw,3.6rem) 0; border-top:1px solid var(--line);
}
.post:first-of-type{ border-top:0; padding-top:0 }
.post__fig{ margin:0; position:sticky; top:6rem }
.post__frame{ overflow:hidden; background:var(--paper-2) }
.post__frame img{ width:100%; height:auto; display:block }
.post__body h2{ margin:.2rem 0 1rem; font-size:clamp(1.5rem,3vw,2.1rem); line-height:1.18 }
.post__body p{ font-size:var(--t-body); line-height:1.72; color:var(--ink-2); margin:0 0 1rem }
.post__date{ font-family:var(--sans); font-size:var(--t-micro); letter-spacing:.2em; color:var(--ink-3); margin:0 }
.post__door{ font-family:var(--serif); font-style:italic; font-size:var(--t-lead); color:var(--ink) !important; margin-top:1.5rem !important }
.post__links{ display:flex; flex-wrap:wrap; align-items:center; gap:1rem 1.4rem; margin:1.4rem 0 0 !important }
.post__src{ font-family:var(--sans); font-size:var(--t-micro); letter-spacing:.14em; text-transform:uppercase; color:var(--ink-3) }

/* ---------- V4: her own face, and the dogs ------------------------------ */
/* The white plate used to sit glued to the text column and ride up beside the
   heading (Alex, 2026-09-04). The figure now has its own column, a real gutter,
   and it starts below the heading's baseline instead of level with it. */
.two__grid{
  display:grid; grid-template-columns:minmax(0,1fr) minmax(0,.58fr);
  column-gap:clamp(3rem, 7vw, 6rem); row-gap:2rem; align-items:start;
}
.two__grid > figure{ margin-top:calc(var(--t-head) * 1.15) }
.dogs{ display:grid; grid-template-columns:repeat(4, minmax(0,1fr)); gap:clamp(.9rem,2vw,1.6rem) }
.dog{ margin:0 }
.dog__frame{ overflow:hidden; background:var(--paper-2); aspect-ratio:1/1 }
.dog__frame img{ width:100%; height:100%; object-fit:cover }


/* ---------- V5: the instagram strip (home) ------------------------------
   Her most recent work lives on the feed, so the home ends by pointing there
   with the photographs themselves rather than with the Instagram mark. */
.ig__head{
  display:flex; flex-wrap:wrap; justify-content:space-between; align-items:flex-end;
  gap:1.2rem; margin-bottom:var(--gap-s);
}
.ig__h2{ max-width:18ch }
.ig__grid{ display:grid; grid-template-columns:repeat(6, minmax(0,1fr)); gap:clamp(.5rem,1.1vw,1rem) }
.ig__grid .plate{ padding:clamp(.3rem,.5vw,.45rem) }
.ig__grid .plate__inner{ aspect-ratio:1/1 }
.ig__img{ width:100%; height:100%; object-fit:cover; transition:transform 1.1s var(--ease) }
.ig__grid a:hover .ig__img{ transform:scale(1.06) }

/* A photograph whose whole point is its colour opts out of the B&W default:
   the Cappadocia balloon is the reason this rule exists. */
html[data-palette="bw"] img.always-color{ filter:none }

/* ---------- V5: the farewell (home) -------------------------------------
   The closing picture opens out of a small window into the full frame as you
   scroll: no card over it, the image itself is the reveal. --p is the scroll
   progress through the section, written by site.js (0 -> 1). */
.farewell{ position:relative; padding:0; background:var(--paper-2); height:160vh; --p:0 }
.farewell::before{
  content:""; position:absolute; inset:0; z-index:0; pointer-events:none; opacity:.05;
  background:url("../textures/light-wash-2400x1600.png?v=v5-1") center / cover no-repeat;
}
.farewell__frame{
  position:sticky; top:calc((100svh - min(88svh, 780px)) / 2);
  overflow:hidden; height:min(88svh, 780px);
  clip-path:inset(calc(18% * (1 - var(--p))) calc(12% * (1 - var(--p))));
  will-change:clip-path;
}
.farewell__img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  transform:scale(calc(1.06 - .06 * var(--p)));
}
.farewell__shade{
  position:absolute; inset:0; z-index:2; pointer-events:none;
  background:
    linear-gradient(to top, rgba(0,0,0,.52) 0%, rgba(0,0,0,.36) 24%, rgba(0,0,0,.16) 50%, rgba(0,0,0,.02) 74%, rgba(0,0,0,0) 100%),
    radial-gradient(110% 80% at 26% 76%, rgba(0,0,0,.42) 0%, rgba(0,0,0,.22) 40%, rgba(0,0,0,0) 72%);
}
.farewell__line{
  position:absolute; z-index:3; left:var(--pad); bottom:clamp(2.6rem,7vh,5rem);
  max-width:min(22ch,80%);
  color:#FCFBF8; font-family:var(--serif); font-weight:300;
  font-size:clamp(1.85rem,4.4vw,3.4rem); line-height:1.1; margin:0;
  opacity:0; filter:blur(10px); transform:translateY(10px);
  transition:opacity 1.4s var(--ease) .5s, filter 1.4s var(--ease) .5s, transform 1.4s var(--ease) .5s;
  text-shadow:0 1px 3px rgba(0,0,0,.9), 0 2px 18px rgba(0,0,0,.8), 0 8px 60px rgba(0,0,0,.7);
}
.farewell.is-lit .farewell__line{ opacity:1; filter:blur(0); transform:none }
.farewell__cta{
  position:relative; z-index:3; text-align:center;
  padding:clamp(2rem,5vw,3.4rem) 0 var(--gap-l);
  background:var(--paper);
}

.closing{ text-align:center }
.btn{
  display:inline-flex; align-items:center; gap:.6rem; text-decoration:none;
  font-size:var(--t-micro); letter-spacing:.2em; text-transform:uppercase;
  border:1px solid var(--ink-3); border-radius:999px; padding:.85rem 1.7rem; color:var(--ink);
  background:none; cursor:pointer;
  transition:background .3s var(--ease), color .3s var(--ease);
}
.btn:hover{ background:var(--ink); color:var(--paper) }
.btn--ghost{ border-color:var(--line); color:var(--ink-2) }
.btn--ghost:hover{ background:none; color:var(--ink); border-color:var(--ink-3) }
.btn .arrow{ width:15px; height:15px; flex:none }

/* ---------- 6. page heads ------------------------------------------------ */
.pagehead{ padding:var(--gap) 0 var(--gap-s) }
/* the head already carries its own bottom space; don't stack a second one */
.pagehead + .sec--tight{ padding-top:0 }
.pagehead h1{ max-width:20ch }
.pagehead .lead{ margin-top:1.1rem }

/* ---------- 7. portfolio + albums ---------------------------------------- */
.albums{ display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:clamp(1.2rem,3vw,2.4rem); align-items:start }
.album-card{
  background:none; border:0; padding:0; text-align:left; cursor:pointer; display:block; width:100%;
}
.album-card__frame{ display:block; overflow:hidden; background:var(--paper-2); position:relative }
.album-card__frame img{ width:100%; height:auto; display:block; transition:transform 1.1s var(--ease) }
.album-card:hover .album-card__frame img{ transform:scale(1.04) }
.album-card__count{
  position:absolute; right:.7rem; bottom:.7rem; background:rgba(12,11,10,.55); color:#F6F2EA;
  font-size:var(--t-micro); letter-spacing:.18em; text-transform:uppercase; padding:.3rem .66rem;
  border-radius:999px; backdrop-filter:blur(4px);
}
.album-card__name{ display:block; font-family:var(--serif); font-size:var(--t-head); line-height:1.2; margin:.9rem 0 .25rem }
.album-card__line{ display:block; font-size:var(--t-body); color:var(--ink-3); margin:0 0 .4rem; line-height:1.6 }

/* ---- the four albums, stacked on scroll ---------------------------------
   Three equal tiles and a short fourth read as a mistake (Alex, 2026-09-02).
   Each album is now one full-width card that pins under the masthead while
   the next one rides up over it, each resting 1.35rem lower than the last so
   the pile stays visible. Photographs are contained, never cropped, so a face
   is never cut to fill a box. Below 861px, and whenever motion is reduced,
   .is-stack is never applied and this is a plain vertical list.             */
.albums.is-stack{ display:block }
.albums.is-stack .album-card{
  position:sticky; top:calc(4.8rem + var(--i,0) * 1.35rem);
  display:grid; grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);
  gap:clamp(1rem,2.6vw,2.2rem); align-items:center;
  background:var(--paper); border:1px solid var(--line);
  padding:clamp(.75rem,1.5vw,1.15rem);
  margin:0 0 clamp(2rem,7vh,4.5rem);
  transform-origin:50% 0; will-change:transform;
  box-shadow:0 26px 60px -46px rgba(8,7,6,.55);
}
.albums.is-stack .album-card:last-child{ margin-bottom:0 }
.albums.is-stack .album-card__frame{
  display:flex; align-items:center; justify-content:center; max-height:64vh; background:none;
}
.albums.is-stack .album-card__frame img{
  width:auto; max-width:100%; max-height:64vh; height:auto; object-fit:contain;
}
.albums.is-stack .album-card__name{ margin-top:0 }
.albums.is-stack .album-card__count{ right:.9rem; bottom:.9rem }

/* the viewer: fullscreen, arrows always visible, swipeable */
.viewer{
  position:fixed; inset:0; z-index:120; background:var(--paper);
  display:none; flex-direction:column;
}
.viewer.is-open{ display:flex }
.viewer__bar{
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
  padding:.9rem var(--pad); border-bottom:1px solid var(--line); flex:none;
}
.viewer__title{ font-family:var(--serif); font-size:var(--t-lead); margin:0 }
.viewer__meta{ font-size:var(--t-micro); letter-spacing:.2em; text-transform:uppercase; color:var(--ink-3) }
.viewer__close{
  background:none; border:1px solid var(--line); border-radius:999px; cursor:pointer;
  padding:.5rem .85rem; font-size:var(--t-micro); letter-spacing:.17em; text-transform:uppercase;
  color:var(--ink-2); display:inline-flex; align-items:center; gap:.45rem;
}
.viewer__stage{
  position:relative; flex:1 1 auto; min-height:0; display:grid; place-items:center;
  padding:clamp(.8rem,2.4vw,1.8rem) clamp(3.4rem,7vw,5rem); touch-action:pan-y;
}
.viewer__slide{
  position:absolute; inset:clamp(.8rem,2.4vw,1.8rem) clamp(3.4rem,7vw,5rem);
  display:grid; place-items:center; opacity:0; pointer-events:none;
  transition:opacity .5s var(--ease);
}
.viewer__slide.is-on{ opacity:1; pointer-events:auto }
.viewer__slide img{ max-width:100%; max-height:100%; width:auto; height:auto; object-fit:contain; box-shadow:var(--shadow) }
.viewer__nav{
  position:absolute; top:50%; transform:translateY(-50%);
  width:clamp(2.4rem,4vw,3rem); height:clamp(2.4rem,4vw,3rem); border-radius:50%;
  background:var(--mat); border:1px solid var(--line); cursor:pointer; z-index:3;
  display:grid; place-items:center; color:var(--ink-2); box-shadow:var(--shadow);
}
.viewer__nav:hover{ color:var(--ink) }
.viewer__nav--prev{ left:clamp(.4rem,1.4vw,1rem) }
.viewer__nav--next{ right:clamp(.4rem,1.4vw,1rem) }
.viewer__foot{
  flex:none; padding:.85rem var(--pad) 1.1rem; border-top:1px solid var(--line);
  display:flex; align-items:center; justify-content:space-between; gap:1rem;
}
.viewer__cap{ font-size:var(--t-body); color:var(--ink-2); margin:0; max-width:46ch; line-height:1.6 }
.viewer__dots{ display:flex; gap:.35rem; flex-wrap:wrap; justify-content:flex-end }
.viewer__dot{
  width:7px; height:7px; border-radius:50%; border:1px solid var(--ink-3); background:none;
  padding:0; cursor:pointer;
}
.viewer__dot.is-on{ background:var(--ink) }

/* ---------- 8. destinations map ------------------------------------------ */
/* The stage is two columns from 861px up: the map on the left, the card in a
   reserved strip on the right. The card is never a lid on the map and never
   parked off-canvas — the old `transform:translateX(103%)` was still painted,
   still visible, and pushed the document 266px wider than the window. */
.mapstage{ position:relative; display:grid; grid-template-columns:minmax(0,1fr) min(24rem, 30%) }
.mapwrap{
  position:relative; height:min(78vh, 46rem); min-height:29rem;
  border:1px solid var(--line); background:var(--sea); overflow:hidden;
}
.mapwrap svg{ display:block; width:100%; height:100%; touch-action:none; cursor:grab }
.mapwrap svg.is-dragging{ cursor:grabbing }
.land{ fill:var(--land); stroke:var(--coast); stroke-width:.7; vector-effect:non-scaling-stroke }
.lake{ fill:var(--sea); stroke:var(--coast); stroke-width:.5; vector-effect:non-scaling-stroke }

.pin{ pointer-events:none }
.pin circle.dot{ fill:var(--accent-2); stroke:var(--paper); stroke-width:1.2; vector-effect:non-scaling-stroke }
.pin circle.halo{ fill:none; stroke:var(--accent-2); opacity:.45; vector-effect:non-scaling-stroke; stroke-width:1 }
.pin.travel circle.dot{ fill:none; stroke:var(--ink-3); stroke-width:1.4 }
.pin.travel circle.halo{ display:none }
html[data-theme="dark"] .pin circle.dot{ filter:drop-shadow(0 0 6px rgba(216,178,120,.85)) }
html[data-theme="dark"] .pin.travel circle.dot{ stroke:var(--ink-2); filter:drop-shadow(0 0 3px rgba(200,193,182,.5)) }
/* the labels live in their own layer, drawn after every pin */
.labels{ pointer-events:none }
text.pinlabel{
  font-family:var(--sans); font-weight:400; letter-spacing:.14em; text-transform:uppercase;
  fill:var(--ink-2); paint-order:stroke; stroke:var(--paper); stroke-width:3px; stroke-linejoin:round;
}
html[data-theme="dark"] text.pinlabel{ stroke:var(--sea) }
.pin.is-hot circle.dot,.pin:focus-visible circle.dot{ transform:scale(1.35); transform-box:fill-box; transform-origin:center }
.pin:focus-visible{ outline:none }
.pin.is-hot circle.halo,.pin:focus-visible circle.halo{ opacity:1 }
svg.hide-session .pin.session,svg.hide-session text.pinlabel.session{ display:none }
svg.hide-travel .pin.travel,svg.hide-travel text.pinlabel.travel{ display:none }

.region{ pointer-events:none }
.region circle{ fill:transparent; stroke:var(--accent); stroke-dasharray:3 4; stroke-width:1.2; vector-effect:non-scaling-stroke; opacity:.75 }
text.regionlabel{
  /* no font-size here: the layout pass sets it per frame in user units, and a
     CSS length would freeze the label at 11 SVG units — three unreadable pixels
     at the fitted view on a phone. */
  font-family:var(--sans); letter-spacing:.18em; text-transform:uppercase; fill:var(--accent);
  paint-order:stroke; stroke:var(--paper); stroke-width:3px; stroke-linejoin:round;
}
/* geography anchors: what a stranger reads first */
.anchor{
  font-family:var(--sans); letter-spacing:.3em; text-transform:uppercase; fill:var(--ink-3);
  paint-order:stroke; stroke:var(--paper); stroke-width:3px; stroke-linejoin:round; opacity:.9;
  pointer-events:none;
}
html[data-theme="dark"] .anchor{ stroke:var(--sea) }
html[data-theme="dark"] text.regionlabel{ stroke:var(--sea) }
.region.is-hot circle,.region:focus-visible circle{ opacity:1; stroke-dasharray:none }
.region:focus-visible{ outline:none }

.maphud{ position:absolute; z-index:5; font-family:var(--sans) }
.maphud--hint{
  top:.85rem; left:.9rem; font-size:var(--t-micro); letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-2); max-width:70%; pointer-events:none; margin:0;
  background:color-mix(in srgb, var(--paper) 84%, transparent); border:1px solid var(--line);
  border-radius:999px; padding:.34rem .8rem; backdrop-filter:blur(6px);
  transition:opacity .6s var(--ease);
}
.maphud--hint.is-gone{ opacity:0 }
.maphud--top{ top:.85rem; right:.9rem; display:flex; gap:.4rem }
.maphud--legend{
  bottom:2.6rem; left:50%; transform:translateX(-50%); display:flex; gap:.35rem; align-items:center;
  justify-content:center; flex-wrap:wrap; max-width:calc(100% - 1.6rem);
  background:color-mix(in srgb, var(--paper) 85%, transparent); border:1px solid var(--line);
  border-radius:999px; padding:.28rem; backdrop-filter:blur(6px);
}
.maphud--legend button{
  font-family:var(--sans); font-size:var(--t-micro); letter-spacing:.15em; text-transform:uppercase;
  color:var(--ink-2); background:none; border:0; border-radius:999px; padding:.44rem .8rem; cursor:pointer;
  white-space:nowrap; max-width:100%; overflow:hidden; text-overflow:clip;
}
/* on a phone the longest label is Portuguese ("As minhas viagens"); tighten the
   letter-spacing and the padding so both chips stay inside the map frame. */
@media (max-width:560px){
  .maphud--legend{ gap:.15rem; padding:.22rem; max-width:calc(100% - 1rem) }
  .maphud--legend button{ letter-spacing:.06em; padding:.4rem .5rem }
  .maphud--legend button i{ width:8px; height:8px; margin-right:.3rem }
}
.maphud--legend button i{ display:inline-block; width:9px; height:9px; border-radius:50%; margin-right:.42rem; vertical-align:-1px }
.maphud--legend button.is-session i{ background:var(--accent-2) }
.maphud--legend button.is-travel i{ border:1.4px solid var(--ink-3) }
.maphud--legend button[aria-pressed="false"]{ opacity:.36 }
.mapchip{
  font-family:var(--sans); font-size:var(--t-micro); letter-spacing:.15em; text-transform:uppercase;
  background:var(--mat); color:var(--ink-2); border:1px solid var(--line); border-radius:999px;
  padding:.44rem .9rem; cursor:pointer;
}
.mapchip:hover{ color:var(--ink) }
.mapchip[hidden]{ display:none }
.mapcredit{
  position:absolute; z-index:4; bottom:.45rem; right:.7rem; font-family:var(--sans);
  font-size:var(--t-micro); letter-spacing:.06em; color:var(--ink-3); pointer-events:none;
  margin:0;
}
.mapcard{
  grid-column:2; min-width:0; min-height:0;
  background:var(--mat); border:1px solid var(--line); border-left:0;
  display:flex; flex-direction:column; overflow-y:auto;
}
/* Closed, the strip is not empty and it is not a ghost: it says what the map
   is, in her voice, and the place takes its place when one is chosen. */
.mapcard__rest{ padding:1.3rem 1.2rem; font-size:var(--t-body); line-height:1.6; color:var(--ink-2); margin:auto 0 }
.mapcard:not(.is-open) .mapcard__head,
.mapcard:not(.is-open) .mapcard__photos,
.mapcard:not(.is-open) .mapcard__story,
.mapcard:not(.is-open) .mapcard__cta{ display:none }
.mapcard.is-open .mapcard__rest{ display:none }
.mapcard__head{ padding:1.1rem 1.2rem .7rem; display:flex; justify-content:space-between; gap:.8rem; align-items:flex-start }
/* the head is a flex row: without min-width:0 the title column refuses to
   shrink, and a name with no space in it (pt "Linderhof / Oberammergau")
   paints straight past the card edge. */
.mapcard__head > div{ min-width:0; flex:1 1 auto }
.mapcard__kind{ font-size:var(--t-micro); letter-spacing:.2em; text-transform:uppercase; color:var(--ink-3); margin:0 0 .3rem }
/* hyphens:manual, not auto: auto printed "Oberammer-gau" at 1024 and 861 —
   a hyphen the place name does not have (Alex, 2026-09-02). The name is
   allowed to shrink instead, which is what makes the longest one fit. */
.mapcard__name{
  font-size:clamp(1.35rem, 1.9vw, var(--t-head)); margin:0;
  overflow-wrap:break-word; word-break:normal; hyphens:manual;
}
.mapcard__close{
  background:none; border:0; cursor:pointer; color:var(--ink-2);
  /* a real target for a thumb, not a 26px cross */
  min-width:44px; min-height:44px; padding:0; margin:-.6rem -.5rem 0 0;
  display:flex; align-items:center; justify-content:center; flex:none;
}
.mapcard__photos{ padding:0 1.2rem 1rem; display:grid; gap:.8rem; justify-items:center }
/* capped so a 750px file is never printed at 666px, which is what the
   full-width card did at 768 */
.mapcard__photos img{ width:100%; max-width:min(100%, 24rem); height:auto; background:var(--paper-2) }
.mapcard__photos:empty{ display:none }
.mapcard__story{ padding:0 1.2rem 1.3rem; font-size:var(--t-body); line-height:1.6; color:var(--ink-2); margin:0 }
.mapcard__cta{
  margin:auto 1.2rem 1.2rem; font-size:var(--t-micro); letter-spacing:.16em; text-transform:uppercase;
  color:var(--accent); text-decoration:none; border-top:1px solid var(--line); padding-top:.9rem;
}

/* ---------- 9. about ------------------------------------------------------ */
.about__grid{ display:grid; grid-template-columns:minmax(0,.8fr) minmax(0,1fr); gap:clamp(2rem,5vw,4.5rem); align-items:start }

.steps{ display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:clamp(1.4rem,3vw,2.6rem); counter-reset:step }
.step{ border-top:1px solid var(--line); padding-top:1.1rem }
.step__n{
  font-family:var(--sans); font-size:var(--t-micro); letter-spacing:.24em; color:var(--ink-3);
  display:block; margin-bottom:.7rem;
}
.step h3{ margin-bottom:.5rem }
.step p{ font-size:var(--t-body); line-height:1.62; color:var(--ink-2); margin:0 }

/* ---------- 10. four legs ------------------------------------------------- */
/* Four legs gallery — one rhythm, grouped by shape.
   The three uprights share a 4:5 frame and the one wide frame gets its own 3:2
   row underneath. Nothing is stretched: each photograph is covered into a box
   its own proportion nearly fits (0.727 / 0.903 / 0.817 into 0.8, and 1.489
   into 1.5), so every tile edge lands on the same line and no bottom is ragged. */
/* Four legs opens on type, with one contained photograph beside it — the only
   page on the site that opens this way. The photograph sits in the narrower
   column on purpose: at ~440px it is printed well inside the 1036px file. */
.pethead__grid{
  display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);
  gap:clamp(1.4rem,4vw,3.4rem); align-items:center;
}
.pethead__grid h1{ max-width:14ch }

.petgal{
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr));
  gap:clamp(.9rem,2vw,1.5rem); align-items:stretch;
}
.petgal figure, .petwide figure{ margin:0; display:flex; flex-direction:column }
.petgal .plate__inner{ aspect-ratio:4/5 }
/* the wide frame keeps the same column rhythm and stops at two of the three
   columns: past that it would be printed larger than the file it came from */
.petwide{
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr));
  gap:clamp(.9rem,2vw,1.5rem); margin-top:clamp(.9rem,2vw,1.5rem);
}
.petwide figure{ grid-column:span 2 }
.petwide .plate__inner{ aspect-ratio:3/2 }
.petgal img, .petwide img{ width:100%; height:100%; object-fit:cover; object-position:50% 38% }
.petwide img{ object-position:50% 42% }
.note{
  border:1px solid var(--line); border-radius:.7rem; padding:clamp(1.2rem,3vw,2rem);
  background:var(--mat); max-width:44rem;
}
.note h3{ margin-bottom:.6rem }
.note ul{ margin:0; padding-left:1.1rem; color:var(--ink-2); font-size:var(--t-body); line-height:1.62 }
.note li{ margin-bottom:.5rem }
.note li:last-child{ margin-bottom:0 }

/* ---------- 11. contact --------------------------------------------------- */
.reach{ display:grid; grid-template-columns:repeat(2, minmax(0,1fr)); gap:clamp(1rem,2.4vw,1.8rem) }
.reach a{
  display:block; text-decoration:none; border:1px solid var(--line); border-radius:.7rem;
  padding:clamp(1.2rem,3vw,1.8rem); background:var(--mat);
  transition:border-color .3s var(--ease), transform .3s var(--ease);
}
.reach a:hover{ border-color:var(--ink-3); transform:translateY(-2px) }
.reach h3{ margin-bottom:.35rem }
.reach p{ font-size:var(--t-body); line-height:1.62; color:var(--ink-3); margin:0 }
.reach__k{ display:block; font-size:var(--t-micro); letter-spacing:.22em; text-transform:uppercase; color:var(--ink-3); margin-bottom:.7rem }

.form{ display:grid; gap:1.1rem; max-width:34rem }
.field{ display:grid; gap:.4rem }
.field label{ font-size:var(--t-micro); letter-spacing:.2em; text-transform:uppercase; color:var(--ink-3) }
.field input, .field textarea{
  font:inherit; font-size:var(--t-body); color:var(--ink); background:var(--mat);
  border:1px solid var(--line); border-radius:.45rem; padding:.75rem .9rem; width:100%;
}
.field textarea{ min-height:8.5rem; resize:vertical }
.field input:focus, .field textarea:focus{ outline:2px solid var(--accent); outline-offset:1px; border-color:var(--accent) }
.formnote{ font-size:var(--t-body); line-height:1.62; color:var(--ink-3); margin:0 }

/* ---------- 12. footer ---------------------------------------------------- */
.footer{ border-top:1px solid var(--line); background:var(--paper-2); padding:var(--gap) 0 var(--gap-s) }
.footer__grid{ display:grid; grid-template-columns:minmax(0,1.1fr) minmax(0,1fr) minmax(0,1fr); gap:var(--gap-s) }
.footer__nav{ display:flex; flex-direction:column; gap:.5rem }
.footer__nav a{
  font-size:var(--t-micro); letter-spacing:.2em; text-transform:uppercase; text-decoration:none;
  color:var(--ink-2); display:inline-flex; align-items:center; gap:.45rem;
}
.footer__nav a:hover{ color:var(--ink) }
.footer__reach p{ font-size:var(--t-body); line-height:1.62; color:var(--ink-2) }
.footer__reach a{ color:var(--ink-2) }

/* ---------- 13. responsive ------------------------------------------------ */
/* Same breakpoint the script uses to pick the portrait film and the portrait
   still. That still is composed for this shape, so it stays centred: the 16:9
   end frame is what cut a face in half when a phone cropped it. */
@media (max-width:740px){
  /* the pinned reveal is a desktop gesture; on a phone the picture is simply there */
  .farewell{ height:auto }
  .farewell__frame{ position:relative; clip-path:none; height:min(78svh, 620px) }
  .farewell__img{ transform:none }
  .farewell__line{ opacity:1; filter:none; transform:none }
  .film__still{ background-position:center center }
  /* on a phone the photograph fills the frame, so the words go under it — the
     bottom third of every one of the fourteen frames is hands, cloth, water or
     leaves, never a face. Clear of the controls and of the replay button. */
  .film__vignette{
    background:
      linear-gradient(to top, rgba(8,7,6,.72) 0%, rgba(8,7,6,.42) 22%, rgba(8,7,6,.10) 42%, transparent 56%),
      radial-gradient(130% 90% at 50% 38%, transparent 48%, rgba(8,7,6,.42) 100%);
  }
  .film__beat{
    left:50%; right:auto; top:auto; bottom:6.6rem; transform:translateX(-50%);
    width:min(24rem, calc(100vw - var(--pad)*2)); text-align:center;
    font-size:clamp(1.5rem, 6.2vw, 2rem);
  }
  .film__beat--long{ width:min(24rem, calc(100vw - var(--pad)*2)); font-size:clamp(1.2rem, 5vw, 1.6rem) }
  .film__sig{ font-size:clamp(1.9rem, 8vw, 2.4rem) }
}
@media (max-width:1000px){
  .doors{ grid-template-columns:repeat(2, minmax(0,1fr)) }
  .notes{ grid-template-columns:repeat(2, minmax(0,1fr)) }
  .notes .note:nth-child(3){ grid-column:1 / -1 }
  .notes .note:nth-child(3) .note__frame{ aspect-ratio:16/7 }
  .dogs{ grid-template-columns:repeat(2, minmax(0,1fr)) }
  .footer__grid{ grid-template-columns:1fr 1fr }
  .reach{ grid-template-columns:1fr }
  .steps{ grid-template-columns:1fr }
}
@media (max-width:860px){
  .ig__grid{ grid-template-columns:repeat(3, minmax(0,1fr)) }
  .navbar{ display:none }
  .nav-btn{ display:block }
  .masthead__inner{ gap:.5rem }
  .masthead__inner > .wordmark{ margin-left:auto; margin-right:auto; align-items:center }
  .u-long{ display:none }
  .u-short{ display:inline }
  .hi__grid, .about__grid{ grid-template-columns:1fr }
  .two__grid{ grid-template-columns:1fr; row-gap:2.4rem }
  .two__grid > figure{ margin-top:0 }
  .post{ grid-template-columns:1fr; gap:1.4rem }
  .post__fig{ position:static }
  .voice__set{ grid-template-columns:1fr; gap:1.9rem }
  .pethead__grid{ grid-template-columns:1fr; gap:1.5rem }
  .pethead__grid h1{ max-width:none }
  .albums{ grid-template-columns:1fr }
  /* One column below the desktop grid. Two columns would leave the third
     upright alone beside an empty cell — the ragged half-row the four-legs
     gallery was rebuilt to lose. */
  /* one centred column, capped: a 684px-wide tile would be printing a 785px
     file at almost its own size */
  .petgal, .petwide{ grid-template-columns:minmax(0,26rem); justify-content:center }
  .petwide figure{ grid-column:auto }
  /* The map keeps every pixel of its pin area. The card is the next thing down
     the page, so a second tap on a second pin lands on the map and changes the
     card instead of being swallowed by it. */
  .mapstage{ display:block }
  .mapwrap{ height:min(66vh, 34rem); min-height:22rem }
  .mapcard{
    width:auto; max-height:none; border:1px solid var(--line);
    border-top:0; display:none; overflow:visible;
  }
  .mapcard.is-open{ display:flex }
  /* on a phone the strip does not exist, so neither does its resting line */
  .mapcard .mapcard__rest{ display:none }
  .mapcard__cta{ margin-top:0 }
}
@media (max-width:620px){
  .notes{ grid-template-columns:1fr }
  .notes .note:nth-child(3){ grid-column:auto }
  .notes .note:nth-child(3) .note__frame{ aspect-ratio:4/3 }
  .utility .ctrl--cta{ display:none }
  /* the three controls keep their touch target and lose their words: at 390 the
     words pushed the row 28px past the viewport. The aria-labels still say what
     each one does, in the visitor's language. */
  .utility .ctrl .label{ display:none }
  .utility .ctrl{ padding:.5rem .6rem; gap:0 }
  .lang__trigger svg{ display:none }
  .masthead__inner{ gap:.35rem }
  .footer__grid{ grid-template-columns:1fr }
  .viewer__foot{ flex-direction:column; align-items:flex-start; gap:.6rem }
  .viewer__dots{ justify-content:flex-start }
  .film__replay{ bottom:calc(var(--pad) + 3rem) }
}

@media (prefers-reduced-motion:reduce){
  *{ animation-duration:.001ms !important; animation-iteration-count:1 !important;
     transition-duration:.001ms !important; scroll-behavior:auto !important }
  .reveal{ opacity:1; filter:none; transform:none }
  .farewell__frame{ clip-path:none }
  .farewell__img{ transform:none }
  .farewell__line{ opacity:1; filter:none; transform:none }
}

/* ---------- 14. states and helpers referenced from the HTML and JS -------- */
.label{ display:inline-block }
.lang__trigger{ gap:.38rem }
.footer__brand .wordmark{ margin:0 0 .8rem }
.footer__brand{ display:block }

/* the film, when it cannot or should not play: the still IS the closing frame */
.film--nofilm .film__video{ display:none }
.film--nofilm .film__tools{ display:none }
.film.is-ended .film__scroll{ opacity:1 }
.film.is-paused .film__replay{ display:none }
.film.is-ended .film__tools{ opacity:.55 }

/* the map's geography group */
.view{ pointer-events:auto }
