/* ============================================================
   NASTASI FOODS — story.css   (story.html only)
   ------------------------------------------------------------
   Modelled on pizza-amici.nl/over-ons, rebuilt in the vintage
   system. Six bands, in the order Sergio asked for:

     1. .hist      our history — banner, intro ticket, collage
     2. .mrail     the milestone rail (1983 → today)
     3. .revs      testimonials, staggered, with margin notes
     4. .tl        OUR TEAM on the reference's ruler-timeline
     5. .score     the 4.9-on-Google rating cards
     6. .work      work with us

   Every panel is a .vcard (shapes.css) — nothing here is a plain
   rectangle with a flat border, and no band is dark full-bleed.
   Loaded LAST, after pages.css.
   ============================================================ */

/* ============================================================
   1. OUR HISTORY
   The reference pulls its intro block ~250px up over a wide
   banner photo (.hero-content_wrapper, translateY(-249px)).
   Same move, done with margin so nothing overlaps unpredictably.
   ============================================================ */
.hist { padding-bottom: 0; overflow: hidden; }
/* A height, not an aspect-ratio: `aspect-ratio` plus `max-height` makes the
   figure give up WIDTH once the cap bites, and the banner stops filling
   the wrap. object-fit on the image handles the crop instead. */
.hist__banner {
  position: relative; margin-top: clamp(1.5rem, 3vw, 3rem);
  height: clamp(200px, 26vw, 420px);
  overflow: hidden; border-radius: 2px;
  filter: drop-shadow(0 22px 46px rgba(22, 20, 15, .2));
}
.hist__banner img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* the paper the photo is printed on shows through at the edges */
.hist__banner::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 0 8px var(--bone-pure), inset 0 0 0 10px rgba(22, 20, 15, .35);
}
.hist__postmark {
  position: absolute; right: clamp(1rem, 3vw, 3rem); bottom: clamp(1rem, 2.4vw, 2.2rem);
  z-index: 2; display: grid; place-items: center; text-align: center;
  width: clamp(84px, 9vw, 120px); aspect-ratio: 1; border-radius: 50%;
  border: 2.5px solid var(--stamp); color: var(--stamp);
  background: color-mix(in srgb, var(--bone-pure) 74%, transparent);
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .14em;
  line-height: 1.35; text-transform: uppercase; transform: rotate(-9deg);
}
.hist__postmark b { display: block; font-family: var(--font-display); font-size: 1.5rem; letter-spacing: 0; }

.hist__stage {
  position: relative; z-index: 2;
  margin-top: clamp(-190px, -13vw, -60px);
  display: grid; grid-template-columns: minmax(0, 40fr) minmax(0, 60fr);
  gap: clamp(1rem, 3vw, 3rem); align-items: stretch;
  padding-bottom: clamp(3rem, 5vw, 5.5rem);
}
.hist__card { position: relative; z-index: 3; }
.hist__card .vcard__body { padding: clamp(1.6rem, 1rem + 2vw, 2.6rem); }
.hist__card h2 { font-size: var(--fs-h3); margin-bottom: .9rem; }
.hist__card p { font-size: var(--fs-small); line-height: 1.68; }
.hist__card p + p { margin-top: .85rem; }
.hist__sign {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin-top: 1.3rem; padding-top: .9rem;
  border-top: 1.5px dashed color-mix(in srgb, currentColor 34%, transparent);
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .12em; text-transform: uppercase;
}
.hist__sign b { font-family: var(--font-display); font-size: .95rem; letter-spacing: 0; text-transform: none; }

/* the collage: three tilted stamp-perforated photos, pinned like the
   reference's .hero-content_photo is-1/2/3-about (+4°, −3°, +3°) */
.hist__collage { position: relative; min-height: clamp(300px, 36vw, 520px); }
.hist__photo {
  position: absolute; margin: 0; overflow: hidden;
  background: var(--bone-pure); padding: 8px;
  filter: drop-shadow(0 16px 34px rgba(22, 20, 15, .3));
  will-change: transform;
}
.hist__photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.hist__photo--1 { width: 40%; aspect-ratio: 4 / 5; left: 0;    top: 5%;  transform: rotate(-4deg); z-index: 2; }
.hist__photo--2 { width: 34%; aspect-ratio: 4 / 5; left: 32%;  top: 40%; transform: rotate(3deg);  z-index: 3; }
.hist__photo--3 { width: 36%; aspect-ratio: 5 / 4; right: 0;   top: 2%;  transform: rotate(-3deg); z-index: 1; }
.hist__note {
  position: absolute; right: 2%; bottom: 5%; z-index: 4;
  font-family: var(--font-script); font-weight: 700; line-height: 1.05;
  font-size: clamp(1.4rem, 2.4vw, 2.3rem); color: var(--tomato);
  transform: rotate(-5deg); text-align: center; max-width: 9ch;
}

@media (max-width: 900px) {
  .hist__stage { grid-template-columns: 1fr; margin-top: clamp(-90px, -8vw, -40px); }
  .hist__collage { min-height: 340px; margin-top: 1.5rem; }
  .hist__note { position: static; transform: rotate(-3deg); max-width: none; margin-top: .5rem; }
}

/* ============================================================
   2. THE MILESTONE RAIL — Sorrento → Woodbridge → today
   A dotted rule with punched ticket chips hung off it. Kept
   deliberately different from the team ruler below: chips sit ON
   the line, the ruler hangs cards BELOW ticks.
   ============================================================ */
.mrail { background: var(--bone-pure); }
.mrail__track {
  position: relative; display: grid; gap: clamp(1rem, 2vw, 1.75rem);
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-top: clamp(1.5rem, 3vw, 2.5rem);
}
.mrail__track::before {
  content: ""; position: absolute; left: 4%; right: 4%; top: 34px; height: 0;
  border-top: 2px dashed color-mix(in srgb, var(--ink) 26%, transparent);
}
.mrail__item { position: relative; display: flex; flex-direction: column; align-items: center; text-align: center; }
.mrail__dot {
  position: relative; z-index: 1; width: 15px; height: 15px; margin-top: 27px;
  background: var(--stamp); border: 3px solid var(--bone-pure); border-radius: 50%;
}
.mrail__year {
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .16em;
  color: var(--stamp); order: -1; margin-bottom: .3rem;
}
.mrail__card { margin-top: 1.1rem; width: 100%; }
.mrail__card .vcard__body { padding: clamp(1rem, .7rem + 1vw, 1.5rem); }
.mrail__card h3 { font-size: 1.02rem; line-height: 1.22; margin-bottom: .4rem; }
.mrail__card p { font-size: var(--fs-micro); line-height: 1.55; color: color-mix(in srgb, currentColor 74%, transparent); }
.mrail__item:nth-child(odd) .mrail__card { transform: rotate(-1.2deg); }
.mrail__item:nth-child(even) .mrail__card { transform: rotate(1.2deg); }

@media (max-width: 780px) {
  .mrail__track { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 2.4rem; }
  .mrail__track::before { display: none; }
}

/* ============================================================
   3. REVIEWS
   The reference floats two handwritten notes over a row of cards
   that each sit at a slightly different height. Same idea.
   ============================================================ */
.revs { background: var(--bone-deep); position: relative; overflow: hidden; }
.revs__notes {
  position: relative; display: flex; justify-content: space-between;
  align-items: flex-start; gap: 2rem; flex-wrap: wrap;
  margin-bottom: clamp(1rem, 2vw, 2rem);
}
.revs__note {
  font-family: var(--font-script); font-weight: 700; line-height: 1.02;
  font-size: clamp(1.5rem, 3vw, 2.9rem); color: var(--tomato);
  max-width: 14ch; will-change: transform;
}
.revs__note--r { color: var(--adriatic-ink); text-align: right; transform: rotate(2.5deg); }
.revs__note--l { transform: rotate(-2.5deg); }
.revs__note .star { color: var(--saffron); letter-spacing: -.04em; }

.revs__grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.25rem, 2.4vw, 2.25rem); align-items: start;
}
.revs__card { margin: 0; }
.revs__card:nth-child(1) { margin-top: 1.6rem; transform: rotate(-1.1deg); }
.revs__card:nth-child(2) { margin-top: 0;      transform: rotate(.8deg); }
.revs__card:nth-child(3) { margin-top: 2.6rem; transform: rotate(-.6deg); }
.revs__card .vcard__body { padding: clamp(1.35rem, 1rem + 1.4vw, 2rem); display: flex; flex-direction: column; gap: .85rem; height: 100%; }
.revs__stars { color: var(--saffron); letter-spacing: .14em; font-size: 1.05rem; line-height: 1; }
.revs__card blockquote { font-size: var(--fs-small); line-height: 1.62; margin: 0; }
.revs__card figcaption {
  margin-top: auto; padding-top: .85rem;
  border-top: 1.5px dashed color-mix(in srgb, currentColor 30%, transparent);
}
.revs__card figcaption b { display: block; font-family: var(--font-display); font-size: .98rem; }
.revs__card figcaption span {
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: color-mix(in srgb, currentColor 66%, transparent);
}
@media (max-width: 900px) {
  .revs__grid { grid-template-columns: 1fr; }
  .revs__card:nth-child(n) { margin-top: 0; }
}

/* ============================================================
   4. OUR TEAM — the ruler timeline
   ------------------------------------------------------------
   Reproduced from the reference's .section_timeline:
     · a horizontal track of alternating marker slides and cards
     · each marker = label + 6px tick + a faint dropline
     · each card sits at its own --y (margin-top) and --rot
     · faint 1px ruler lines inside every card, counter-rotated
       so they stay vertical while the card is tilted
     · hover straightens the card and scales it 1.04
   The reference drives it with Swiper (drag + horizontal wheel).
   Here: scroll-linked by default, drag/arrows take over on touch.
   ============================================================ */
.tl { position: relative; background: var(--bone-pure); overflow: hidden; }
.tl__head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap; margin-bottom: clamp(1.5rem, 3vw, 2.75rem);
}
.tl__head .s-head { margin-bottom: 0; }
.tl__script {
  font-family: var(--font-script); font-weight: 700; color: var(--tomato);
  font-size: clamp(1.3rem, 2.2vw, 2rem); line-height: 1; transform: rotate(-4deg);
  display: block; margin-bottom: .35rem;
}

/* the two arrows, top-right like the reference's .slider_btn_layout */
.tl__nav { display: flex; gap: .6rem; }
.tl__btn {
  width: 52px; height: 52px; display: grid; place-items: center;
  border: 2px solid var(--ink); background: var(--bone);
  color: var(--ink); border-radius: 50%; cursor: pointer;
  transition: background var(--dur-fast) ease, color var(--dur-fast) ease,
              transform var(--dur-fast) var(--ease-out), opacity var(--dur-fast) ease;
}
.tl__btn svg { width: 22px; height: 22px; }
.tl__btn:disabled { opacity: .3; cursor: default; }
.tl__btn:not(:disabled):hover { background: var(--ink); color: var(--bone-pure); }
.tl__btn:not(:disabled):active { transform: scale(.93); }
.tl__btn:focus-visible { outline: 3px solid var(--brass); outline-offset: 3px; }

/* the rail. overflow:hidden (the reference leaves it visible and lets the
   100vh droplines run into the next section — that bleeds through our
   bands, so the droplines stop at the rail and fade instead) */
.tl__viewport {
  position: relative; overflow: hidden;
  cursor: grab; touch-action: pan-y;
  /* a hairline baseline so the droplines have somewhere to land */
  border-bottom: 1.5px solid color-mix(in srgb, var(--ink) 18%, transparent);
}
.tl__viewport:focus-visible { outline: 3px solid var(--brass); outline-offset: 4px; }
.tl__viewport[data-dragging="true"] { cursor: grabbing; }
/* Height comes from the tallest card plus its own --y offset, so no scatter
   value can ever push a card out of the rail. The droplines are absolutely
   positioned, contribute nothing to height, and get clipped here. */
.tl__track {
  display: flex; align-items: stretch;
  width: max-content; will-change: transform;
}

/* --- marker slide --- */
.tl__marker {
  flex: none; padding: 0 clamp(1.1rem, 2vw, 2rem);
  display: flex; align-items: flex-start;
}
.tl__marker-inner { display: flex; flex-direction: column; align-items: center; }
.tl__marker-label {
  font-family: var(--font-mono); font-size: .74rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--stamp); margin-bottom: .45em; white-space: nowrap;
}
.tl__tick { position: relative; width: 6px; height: 6px; background: var(--ink); flex: none; }
.tl__tick::after {
  content: ""; position: absolute; top: 6px; left: 50%; transform: translateX(-50%);
  width: 1px; height: 1000px;
  background: linear-gradient(to bottom, color-mix(in srgb, var(--ink) 42%, transparent), transparent 78%);
}

/* --- content card --- */
.tl__slide {
  flex: none; align-self: flex-start; position: relative;
  width: clamp(206px, 18vw, 250px);
  padding: 0 clamp(.5rem, 1vw, 1rem);
  margin-top: var(--y, 5rem); margin-bottom: clamp(1rem, 2vw, 2rem);
  transform: rotate(var(--rot, 0deg));
  transition: transform 300ms ease;
}
@media (hover: hover) and (pointer: fine) {
  .tl__slide:hover { transform: rotate(0deg) scale(1.04); z-index: 4; }
  .tl__slide:hover .tl__lines { transform: rotate(0deg) scale(.9615); }
}
/* the faint ruler lines behind each card. They counter-rotate so they stay
   plumb while the card is tilted — straight from the reference. */
.tl__lines {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  display: flex; justify-content: space-around; align-items: flex-start;
  transform: rotate(var(--rot-inv, 0deg));
  transition: transform 300ms ease;
}
.tl__lines i { display: block; width: 1px; background: var(--ink); opacity: .12; }
.tl__lines i:nth-child(odd)  { height: 100%; }
.tl__lines i:nth-child(even) { height: 60%; margin-top: 20%; }

.tl__card { position: relative; z-index: 1; }
.tl__card .vcard__body { padding: 11px 11px 0; }
/* The card is a frame, so the photograph is cropped BY it and can never
   reach past its outline.

   `overflow: hidden` alone was not enough, because the outline is not the
   box. vintage-card.js scoops a bite out of every corner — the inner printed
   rule is an arc of radius 18.75 centred ON the corner point, at an 11px
   inset — and .vcard__body's 11px padding puts the frame's SQUARE corners
   exactly on those centres. Distance from the arc's centre: 0. So the top
   two corners of every photograph were printed past the card's edge, on
   nothing, which is what read as the picture escaping the card.

   Two radial-gradient masks reproduce the same arcs at the frame's own top
   corners, so the photo now fills precisely to the printed rule. Only the
   standard `mask-composite` is declared: with the -webkit- one present too,
   Chrome takes the legacy keyword set and the mask collapses (see CLAUDE.md).
   The bottom corners sit mid-card, well clear of any bite, and are left
   square on purpose. */
.tl__frame {
  --vc-bite: 18.75px;            /* = the inner rule's corner radius */
  position: relative; overflow: hidden; aspect-ratio: 4 / 5;
  background: var(--bone-deep);
  mask:
    radial-gradient(var(--vc-bite) at 0 0,    #0000 98%, #000) 0 0 / 100% 100% no-repeat,
    radial-gradient(var(--vc-bite) at 100% 0, #0000 98%, #000) 0 0 / 100% 100% no-repeat;
  mask-composite: intersect;
}
.tl__frame img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The bottom padding is geometry, not taste. vintage-card.js scoops a bite
   of radius R=20 out of every corner, centred ON the corner of the outer
   path (itself 6px in) — so near a corner the paper stops 20px away from
   that point, not 6px. At the old .9rem the caption's last line ended up
   14.4px above the card edge and 15px in from its side: 12.3px from the
   corner centre, i.e. INSIDE the bite and printed on nothing. A point is
   safe when its distance from the corner is >= R, and vertical distance
   alone satisfies that, whatever the line's width — so 1.75rem (28px, i.e.
   22px clear of the path) clears both bottom corners on every card at every
   width. Raise it, never lower it, if the caption ever grows a third line. */
.tl__cap { padding: .7rem .25rem 1.75rem; }
.tl__cap b { display: block; font-family: var(--font-display); font-size: 1.02rem; line-height: 1.18; }
.tl__cap span {
  display: block; margin-top: .18rem;
  font-family: var(--font-mono); font-size: .64rem; letter-spacing: .12em;
  text-transform: uppercase; color: color-mix(in srgb, currentColor 66%, transparent);
}

/* Entrance: cards rise into place once the rail is on screen. Armed by the
   script (data-anim), never by the stylesheet alone — if story-page.js
   fails to load, the team is simply there rather than invisible. */
.tl[data-anim] .tl__slide,
.tl[data-anim] .tl__marker-inner { opacity: 0; transform-origin: 50% 0; }
.tl[data-anim] .tl__slide { transform: rotate(var(--rot, 0deg)) translateY(26px); }
.tl[data-anim] .tl__marker-inner { transform: translateY(14px); }
.tl[data-anim].is-in .tl__slide {
  opacity: 1; transform: rotate(var(--rot, 0deg));
  transition: opacity 520ms var(--ease-out) var(--d, 0ms), transform 520ms var(--ease-out) var(--d, 0ms);
}
.tl[data-anim].is-in .tl__marker-inner {
  opacity: 1; transform: none;
  transition: opacity 420ms var(--ease-out) var(--d, 0ms), transform 420ms var(--ease-out) var(--d, 0ms);
}
.tl__hint {
  margin-top: 1.1rem; display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  font-family: var(--font-mono); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-faint);
}

@media (prefers-reduced-motion: reduce) {
  .tl[data-anim] .tl__slide,
  .tl[data-anim] .tl__marker-inner { opacity: 1; transition: none; }
  .tl[data-anim] .tl__slide { transform: rotate(var(--rot, 0deg)); }
  .tl[data-anim] .tl__marker-inner { transform: none; }
  .tl__lines { transition: none; }
}
@media (max-width: 700px) {
  .tl__head { flex-direction: column; align-items: flex-start; }
}

/* ---- the brick course between bands (shapes.css .edge) ----
   It has to sit exactly on the seam, with the band above showing
   through the gaps, so it is pinned rather than left in flow. */
.st-edge {
  position: absolute; left: 0; right: 0; bottom: 0; margin: 0; z-index: 4;
}

/* ============================================================
   5. THE RATING CARDS
   The reference states this on three angled ribbons. Ribbons are
   already spoken for on the home page, so here the same three
   claims become punched tag-cards — the .tag-card shape from the
   reference's work-at block, with its two holes.
   ============================================================ */
.score { position: relative; background: var(--bone); }
.score__grid {
  display: grid; grid-template-columns: minmax(0, 1.15fr) repeat(2, minmax(0, 1fr));
  gap: clamp(1.1rem, 2.2vw, 2rem); align-items: stretch;
}
.score__card { position: relative; }
.score__card:nth-child(1) { transform: rotate(-1.4deg); }
.score__card:nth-child(2) { transform: rotate(1deg); }
.score__card:nth-child(3) { transform: rotate(-.8deg); }
.score__card .vcard__body {
  padding: clamp(1.5rem, 1rem + 1.8vw, 2.4rem) clamp(2.2rem, 1.4rem + 2.4vw, 3.2rem);
  text-align: center; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: .5rem; height: 100%;
}
/* the two punched holes, left and right, that make it a luggage tag */
.score__card::before, .score__card::after {
  content: ""; position: absolute; top: 50%; z-index: 3;
  width: 13px; height: 13px; border-radius: 50%;
  transform: translateY(-50%);
  background: var(--bone);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--ink) 55%, transparent);
}
.score__card::before { left: 14px; }
.score__card::after  { right: 14px; }
.score__n {
  font-family: var(--font-display); font-weight: 600;
  font-size: clamp(3rem, 2rem + 4vw, 5.4rem); line-height: .92; letter-spacing: -.03em;
}
.score__stars { display: flex; gap: .12em; color: var(--saffron); }
.score__stars svg { width: 20px; height: 20px; }
.score__lbl {
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .2em;
  text-transform: uppercase;
}
.score__sub { font-size: var(--fs-micro); color: color-mix(in srgb, currentColor 72%, transparent); max-width: 26ch; }
.score__card h3 { font-size: var(--fs-h4); line-height: 1.2; }
@media (max-width: 860px) {
  .score__grid { grid-template-columns: 1fr; }
  .score__card:nth-child(n) { transform: rotate(0deg); }
}

/* ============================================================
   6. WORK WITH US
   The reference's .section_work-at: a centred CTA card, an
   accolade tag, a handwritten note, two photos and a counter.
   ============================================================ */
.work { position: relative; overflow: hidden; }
.work__stage {
  position: relative; display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(1.5rem, 3.5vw, 3.5rem); align-items: center;
}
.work__cta .vcard__body { padding: clamp(1.8rem, 1.2rem + 2.4vw, 3rem); }
.work__cta h2 { font-size: var(--fs-h2); line-height: 1.05; max-width: 15ch; }
.work__cta p { margin-top: 1rem; font-size: var(--fs-small); line-height: 1.66; max-width: 44ch; }
.work__roles {
  display: flex; flex-wrap: wrap; gap: .45rem; margin-top: 1.35rem;
}
.work__roles li {
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .1em;
  text-transform: uppercase; padding: .35rem .7rem;
  border: 1.5px dashed color-mix(in srgb, currentColor 40%, transparent);
}
.work__actions { display: flex; gap: .9rem; flex-wrap: wrap; margin-top: 1.6rem; }

.work__collage { position: relative; min-height: clamp(340px, 34vw, 460px); }
.work__photo {
  position: absolute; margin: 0; overflow: hidden;
  background: var(--bone-pure); padding: 8px;
  filter: drop-shadow(0 18px 36px rgba(22, 20, 15, .3));
  will-change: transform;
}
.work__photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.work__photo--1 { width: 46%; aspect-ratio: 4 / 5; left: 2%;  top: 4%;   transform: rotate(-3.5deg); z-index: 1; }
.work__photo--2 { width: 42%; aspect-ratio: 4 / 5; right: 4%; top: 26%;  transform: rotate(3deg);    z-index: 2; }
.work__stat {
  position: absolute; left: 34%; bottom: 0; z-index: 3; width: 40%; min-width: 190px;
  transform: rotate(-2deg);
}
.work__stat .vcard__body { padding: 1rem 1.1rem; text-align: center; }
.work__stat .n { display: block; font-family: var(--font-display); font-size: clamp(1.8rem, 3vw, 2.6rem); line-height: 1; font-weight: 600; }
.work__stat .l {
  display: block; margin-top: .3rem; font-family: var(--font-mono);
  font-size: .62rem; letter-spacing: .14em; text-transform: uppercase;
}
.work__note {
  position: absolute; right: 1%; top: 0; z-index: 4;
  font-family: var(--font-script); font-weight: 700; line-height: 1.02;
  font-size: clamp(1.3rem, 2.2vw, 2.1rem); color: var(--tomato);
  transform: rotate(6deg); max-width: 8ch; text-align: center;
}
@media (max-width: 900px) {
  .work__stage { grid-template-columns: 1fr; }
  .work__collage { min-height: 400px; margin-top: 1rem; }
  .work__note { top: auto; bottom: -6%; right: 2%; }
}

/* ============================================================
   Shared: the reveal-on-scroll drift used by the two collages
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .hist__photo, .work__photo, .revs__note { transition: none !important; }
}

/* ============================================================
   THE FILM INTRO — pizza-amici.nl/over-ons, in our clothes
   ------------------------------------------------------------
   Their "OVER ONS" opens on a full-bleed film with ONE card
   floating over it and photo cards struck across the corners.
   Ours had a flat band of type over a letterbox still, which is
   what Sergio called plain. The clip is Pizza.mp4 — food being
   made, not a jar being opened, which is what the Nutella one is.
   ============================================================ */
.hist--film { position: relative; padding-top: 0; }
.hist__film { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.hist__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* CROP THE GENERATOR'S WATERMARK.
     Pizza.mp4 came out of Veo/Gemini with the sparkle glyph struck into the
     bottom-right corner, measured at roughly 92–100% across and 92–100% down.
     There is no ffmpeg on this machine to re-encode, and patching over a mark
     on a MOVING film always shows, so the frame is scaled 1.14 from the
     top-left corner: the mark lands past 105% on both axes and is clipped by
     .hist__film's overflow, while the enlargement keeps the box fully covered
     with no exposed edge. Costs 14% off the right and bottom of a decorative
     background clip. Replace with a clean export and this rule can go. */
  transform-origin: 0 0;
  transform: scale(1.14);
}
/* Enough scrim to carry a paper card and dark type, not so much that the
   film turns into a black band — the one rule in VINTAGE-SYSTEM.md. */
.hist__filmwash {
  position: absolute; inset: 0;
  background:
    radial-gradient(78% 62% at 50% 46%, color-mix(in srgb, var(--bone-pure) 84%, transparent), transparent 76%),
    linear-gradient(180deg,
      color-mix(in srgb, var(--bone-pure) 82%, transparent) 0%,
      color-mix(in srgb, var(--bone) 46%, transparent) 42%,
      color-mix(in srgb, var(--bone) 74%, transparent) 100%);
}
.hist--film > .wrap { position: relative; z-index: 2; }
.hist--film .breadcrumb { padding-top: calc(var(--header-h) + 1rem); }

/* one card, dead centre, with the collage falling in behind it */
.hist--film .hist__stage {
  display: block; position: relative;
  /* The base .hist__stage pulls itself up by as much as 190px so the two-column
     variant can overlap the banner photo above it. There is no banner in the
     film variant — the card just ended up jammed under the header, which is
     what Sergio meant by "la tarjeta central está demasiado arriba". Cancel
     the pull and give the card real room off the top of the film. */
  margin-top: 0;
  padding-block: clamp(3.5rem, 2rem + 5.5vw, 7.5rem) clamp(2rem, 1rem + 4vw, 5rem);
  min-height: clamp(420px, 48vw, 640px);
}
.hist--film .hist__card {
  width: min(100%, 620px); margin-inline: auto;
  transform: rotate(-1.2deg);
  --vc-lift: 0 30px 66px rgba(22, 20, 15, .26);
}
.hist--film .hist__card h1 {
  font-family: var(--font-hero); font-weight: 700;
  font-variation-settings: "wdth" 92;
  font-size: clamp(1.9rem, 1.25rem + 2.4vw, 3.1rem);
  line-height: 1.02; letter-spacing: -.02em; margin: .35rem 0 0;
}
.hist__lede { font-size: var(--fs-lead); color: var(--text-muted); margin: .9rem 0 1.1rem; }
.hist--film .hist__collage {
  position: absolute; inset: 0; z-index: -1; min-height: 0; pointer-events: none;
}
.hist--film .hist__photo--1 { width: clamp(140px, 15vw, 230px); left: 1%;  top: 8%;  }
.hist--film .hist__photo--2 { width: clamp(130px, 14vw, 210px); left: 4%;  top: 56%; }
.hist--film .hist__photo--3 { width: clamp(140px, 15vw, 230px); right: 1%; top: 14%; }
.hist--film .hist__note { position: absolute; right: 3%; bottom: 8%; }
@media (max-width: 1080px) {
  .hist--film .hist__collage { display: none; }
  .hist--film .hist__card { transform: none; }
}
@media (prefers-reduced-motion: reduce) { .hist__video { display: none; } }

/* ============================================================
   THE RIBBON BAND — three tilted bands that ride up over the
   section above them
   ------------------------------------------------------------
   scenes.css owns .ribbon on the home page and story.html does not
   load that sheet, so the band is restated here. Three wraps, not
   the two the old inline version had, and it OVERLAPS: a negative
   margin-top pulls the whole band up into the team fan, and the
   band's own background stays transparent so the fan shows between
   the tilted ends. `position: relative; z-index: 3` is what makes
   the bands paint over the section above rather than under it —
   the same pairing scenes.css documents for the home page.

   --slide is written per frame by story-page.js from the band's own
   passage through the viewport, alternating direction per data-ribbon.
   ============================================================ */
/* THE HOLD. Same mechanism as the home's supplier band: a wrapper taller
   than the section, the section stuck inside it, and the band that follows
   pulled back up by exactly the extra height. The section is TALLER than the
   viewport (heading + a 40rem fan + the arrows), so it cannot stick at
   `top: 0` — that would park its top on the fold and put the arrows
   permanently off screen. story-page.js sets `top` to `min(0, vh - H)`, which
   sticks it by its BOTTOM edge instead: the fan is fully framed and frozen
   while the ribbons climb up over it.

   --tf-hold is written by the same code, so the wrapper's spare height and
   the ribbons' negative margin can never disagree. The fallback value is the
   modest overlap the band had before, for a page where the script never runs.

   The band's own background stays transparent: what should show between the
   tilted ends is the frozen fan, not a slab of paper. */
.teamfan-pin { position: relative; }
.ribbons--story {
  position: relative; z-index: 3; overflow: hidden;
  background: none;
  margin-top: calc(var(--tf-hold, clamp(2.5rem, 1.5rem + 3vw, 6rem)) * -1);
  padding-block: clamp(1.75rem, 1.2rem + 2vw, 3.25rem) 0;
}
/* Positioned + z-indexed for the same reason .reviews is on the home: an
   opaque background alone does not lift a block above a positioned sibling,
   and the sticky fan IS positioned. Without this, Work with us was painted
   underneath the frozen fan as the ribbons dragged it up. */
.work { z-index: 3; }
.ribbons--story .ribbon-wrap {
  position: relative; display: flex; justify-content: center; will-change: transform;
}
.ribbons--story .ribbon-wrap--top { z-index: 1; transform: translateX(var(--slide, 0)) rotate(2deg); }
.ribbons--story .ribbon-wrap--mid { z-index: 3; transform: translate(var(--slide, 0), -.5em) rotate(-1.4deg); }
.ribbons--story .ribbon-wrap--bot { z-index: 2; transform: translate(var(--slide, 0), -1em) rotate(1.8deg); }
.ribbons--story .ribbon {
  position: relative; width: 124vw; flex: none;
  display: flex; align-items: center; justify-content: center;
  gap: clamp(.75rem, 2vw, 2.25rem);
  padding-block: clamp(.8rem, .55rem + 1.1vw, 1.7rem);
}
.ribbons--story .ribbon--brass { background: var(--brass); color: #2a1e08; }
.ribbons--story .ribbon--stamp { background: var(--stamp); color: var(--bone-pure); }
.ribbons--story .ribbon--olive { background: var(--green-800); color: var(--bone); }
.ribbons--story .ribbon__title {
  margin: 0; white-space: nowrap;
  font-family: var(--font-display); font-weight: 600; text-transform: uppercase;
  font-size: clamp(1rem, .45rem + 2.4vw, 2.9rem); line-height: 1; letter-spacing: -.02em;
}
.ribbons--story .ribbon__rule {
  position: absolute; left: 0; right: 0; top: .45em; height: 2px;
  background: currentColor; opacity: .55;
}
.ribbons--story .ribbon__rule--b { top: auto; bottom: .45em; }
@media (prefers-reduced-motion: reduce) {
  .ribbons--story { margin-top: 0; }
  .ribbons--story .ribbon-wrap { transform: none; }
  .ribbons--story .ribbon { width: 100%; }
}

/* The header is transparent over the film, so the band has to reserve its
   height or the breadcrumb prints underneath the nav. */
.hist--film > .wrap { padding-top: calc(var(--header-h) + 1.25rem); }
.hist--film .breadcrumb { padding-top: 0; }

/* ============================================================
   .tl--journey — the milestone rail
   ------------------------------------------------------------
   The four milestones now ride the same rail the team used to
   (tilted photo cards, plumb ruler droplines, editorial scatter).
   Only two things differ, and both are because a milestone carries
   a SENTENCE where a portrait carried a name:

     · the slides are wider
     · .tl__cap grows a paragraph

   The 1.75rem bottom padding on .tl__cap is geometry, not taste —
   see the note above it. Do not lower it here either.
   ============================================================ */
.tl--journey .tl__slide { width: clamp(250px, 24vw, 340px); }
.tl--journey .tl__frame { aspect-ratio: 5 / 4; }
.tl--journey .tl__cap p {
  margin-top: .55rem;
  font-size: var(--fs-micro); line-height: 1.55;
  color: color-mix(in srgb, currentColor 74%, transparent);
}
/* the year markers are the loudest thing on the rail, as they should be */
.tl--journey .tl__marker-label {
  font-family: var(--font-display); font-weight: 600; text-transform: none;
  font-size: clamp(1rem, .85rem + .5vw, 1.35rem); letter-spacing: -.01em;
  color: var(--tomato);
}

/* ============================================================
   THE TEAM FAN
   ------------------------------------------------------------
   Seven cards visible on a shallow arc; the centre one upright and
   full size, the flanks rotating +/- 7/14/21 deg and shrinking as
   they go. assets/js/team-fan.js writes every transform; this sheet
   owns the frame, the tiers and the easing.

   PROGRESSIVE ENHANCEMENT. Until the script stamps
   [data-fan-ready] the stage is a plain horizontal scroller — a
   stylesheet that stacks ten absolutely-positioned cards on one
   spot and waits for JS is one failed request away from a blank
   band. Same reasoning as .tl[data-anim].
   ============================================================ */
.teamfan { position: relative; overflow: hidden; background: var(--bone-pure); }
.teamfan .s-head { margin-bottom: clamp(1.25rem, 2.5vw, 2.25rem); }
.teamfan .tl__script { text-align: center; }

/* --fan-h must match the ideal heights in team-fan.js's hMult(), and the
   45% anchor is measured, not chosen: the card box is the frame PLUS the
   caption below it, so its centre sits lower than the frame's. Anchored at
   50% the two end cards — scaled 0.7756 and pushed down 7.3rem — finished
   47px past the bottom of a 38rem stage and printed through the arrows.
   At 45% of 40rem the lowest card bottoms out at 639 of 640px, and the
   centre card still clears the top when it lifts 2.5rem on hover. */
.fan {
  --fan-w: 19rem;
  --fan-h: 40rem;
  position: relative; z-index: 2;
}
.fan__stage { position: relative; max-width: 80rem; margin-inline: auto; }

/* ---- the no-JS / not-yet-ready state ---- */
.fan:not([data-fan-ready]) .fan__stage {
  display: flex; gap: 1rem; overflow-x: auto; padding-inline: var(--gutter, 1.25rem);
  scroll-snap-type: x mandatory;
}
.fan:not([data-fan-ready]) .fan-card { flex: 0 0 auto; width: 14rem; scroll-snap-align: center; }
.fan:not([data-fan-ready]) .fan__ctrl { display: none; }

/* ---- the fan proper ---- */
.fan[data-fan-ready] .fan__stage { height: var(--fan-h); }
.fan[data-fan-ready] .fan-card {
  position: absolute; left: 50%; top: 45%; width: var(--fan-w);
  margin: calc(var(--fan-w) * -0.7) 0 0 calc(var(--fan-w) * -0.5);
  will-change: transform, opacity;
  /* the entrance overshoots slightly, which is the elastic feel of the
     reference translated into one bezier — no spring solver needed */
  transition: transform 620ms cubic-bezier(.22, 1.18, .3, 1), opacity 380ms ease;
}
.fan[data-fan-ready] .fan-card[data-fan-enter] {
  transition: transform 1080ms cubic-bezier(.16, 1.24, .28, 1), opacity 520ms ease;
}
.fan-card__stamp {
  --perf: 6px; --gap: 17px;
  position: relative; margin: 0; display: block;
  cursor: default;
  /* the label scales with the card, so a 12rem card on a short screen does
     not carry a 19rem card's type. Everything in the caption is in em. */
  font-size: calc(var(--fan-w) / 19);
}
.fan-card__stamp img {
  display: block; width: 100%; aspect-ratio: 5 / 7;
  object-fit: cover; background: var(--bone-deep);
}
/* The caption belongs to the card in FRONT, and to nothing else.
   A fan is a stack: every flank card has the next one lying across its
   lower third, so seven captions at once produced seven half-covered
   names. Only the centre card — and whichever card the cursor is on —
   prints its name; the rest keep the stamp's blank bottom margin, which
   is what a stamp has anyway. The box is always laid out, so nothing
   moves when a caption appears. */
.fan-card__stamp figcaption {
  padding: .7em .35em .3em; text-align: center;
  opacity: 0; transition: opacity 240ms ease;
}
.fan-card[data-fan-front] figcaption,
.fan-card[data-fan-hover] figcaption { opacity: 1; }
.fan:not([data-fan-ready]) .fan-card__stamp figcaption { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .fan-card__stamp figcaption { transition: none; }
}
.fan-card__stamp figcaption b {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: 1em; line-height: 1.18; letter-spacing: -.01em; color: var(--ink);
}
.fan-card__stamp figcaption span {
  display: block; margin-top: .18em;
  font-family: var(--font-mono); font-size: .6em; letter-spacing: .11em;
  text-transform: uppercase; color: var(--text-faint);
}

/* ---- arrows + dots ---- */
/* The margin is CLEARANCE, not spacing. The two end cards are rotated 21deg
   and pushed down 7.3rem, so their axis-aligned box reaches ~35px past the
   bottom of the stage on a short tier — measured at 1280x632, where they
   printed straight through the arrows. z-index 4 keeps the controls on top
   even so; this keeps them from having to. */
.fan__ctrl {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(.9rem, 2vw, 1.6rem);
  margin-top: clamp(2.5rem, 6vh, 3.5rem); position: relative; z-index: 4;
}
.fan__btn {
  width: 48px; height: 48px; flex: none; display: grid; place-items: center;
  border: 2px solid var(--ink); background: var(--bone);
  color: var(--ink); border-radius: 50%; cursor: pointer;
  transition: background var(--dur-fast) ease, color var(--dur-fast) ease,
              transform var(--dur-fast) var(--ease-out);
}
.fan__btn svg { width: 20px; height: 20px; }
.fan__btn:hover { background: var(--ink); color: var(--bone-pure); }
.fan__btn:active { transform: scale(.93); }
.fan__btn:focus-visible { outline: 3px solid var(--brass); outline-offset: 3px; }
.fan__dots { display: flex; align-items: center; gap: .45rem; }
.fan__dots i {
  display: block; width: 7px; height: 7px; border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 20%, transparent);
  transition: background var(--dur-fast) ease, transform var(--dur-fast) var(--ease-out);
}
.fan__dots i[data-on] { background: var(--tomato); transform: scale(1.35); }

@media (max-width: 1023px) { .fan { --fan-w: 17rem; --fan-h: 36rem; } }
@media (max-width: 767px)  { .fan { --fan-w: 15rem; --fan-h: 30rem; } }
@media (max-width: 639px)  { .fan { --fan-w: 13rem; --fan-h: 27rem; } }
@media (max-width: 479px)  { .fan { --fan-w: 11rem; --fan-h: 23rem; } }
/* HEIGHT tiers, not only width. A 40rem stage is 640px, and the viewport
   Sergio actually runs is 632px tall at 100% zoom — the fan alone was taller
   than his screen, so it could never be seen whole however wide the window
   was. team-fan.js reads --fan-h back out of the stylesheet for its vertical
   multiplier, so these are the single source of truth for the fan's scale and
   the two cannot drift apart. */
@media (max-height: 900px) { .fan { --fan-w: 16rem; --fan-h: 32rem; } }
@media (max-height: 760px) { .fan { --fan-w: 14rem; --fan-h: 28rem; } }
@media (max-height: 660px) { .fan { --fan-w: 12rem; --fan-h: 24rem; } }
@media (prefers-reduced-motion: reduce) {
  .fan[data-fan-ready] .fan-card,
  .fan[data-fan-ready] .fan-card[data-fan-enter] { transition: none; }
}

/* ============================================================
   WORK WITH US — the careers copy Sergio supplied
   The roles chips are gone with the copy that introduced them; the
   band now ends on the résumé address, so the last three blocks
   are a question, an invitation and a route.
   ============================================================ */
.work__fit {
  margin-top: 1.5rem; padding-top: 1.1rem;
  border-top: 1.5px dashed color-mix(in srgb, currentColor 32%, transparent);
}
.work__fit h3 { font-size: var(--fs-h4); line-height: 1.2; }
.work__fit p { margin-top: .5rem; }
.work__apply {
  margin-top: 1.35rem !important;
  font-family: var(--font-mono); font-size: .66rem; letter-spacing: .17em;
  text-transform: uppercase; color: var(--text-faint);
}
.work__actions { margin-top: .6rem; }
.work__addr { margin-top: 1.1rem; line-height: 1.7; }
