/* Services + gallery.
   The one stylesheet this workstream owns, loaded by both /servicios and /galeria
   (src/pages/services.js and src/pages/gallery.js ask for it as styles: ['gallery']).
   Splitting it into css/services.css would be tidier and is listed as a request —
   this workstream may not create files outside the four it owns.

   Everything shared lives in css/components.css and is reused rather than copied:
   .menu*, .media, .card, .notice, .btn--primary, .text-link, .lightbox* and the
   icon set all come from there. What follows is only what those pieces do not
   cover: the photo column on a menu row, the square gallery grid, the like button
   and the lightbox's pre-sized image frame.

   Rules this file is built to (docs/reference-bar.json):
     MENU-01   the service rows keep the shared menu typography untouched — this
               file adds layout and a photo, never a card, badge or pill
     PHOTO-01  every tile is 1:1 at every breakpoint; the sources are square too,
               so nothing is letterboxed, pillarboxed or stretched
     CWV-03    tiles reserve their box from aspect-ratio + width/height, and the
               lightbox frame is sized before its image exists
     A11Y-02   no focus ring is removed; the like button relies on base.css's ring
     A11Y-03   the like button and every lightbox control clear 44px
     COLOR-02  one non-neutral ink is added (--blush-ink, on the liked heart) and
               it is a glyph, never a flooded area
     RADIUS-01 photos keep --radius-photo, controls --radius-pill; nothing new
     SPACE-01  gaps come from the 8px token scale only
     ICON-01   heart, chevrons and close are line icons on .icon, no emoji
*/

/* ---- shared page intro --------------------------------------------------- */
/* Left-aligned, measure-capped, never centred (ALIGN-01): Spanish runs long and a
   centred multi-line lede rags on both edges. */

.svc-intro,
.gallery-intro {
  display: grid;
  gap: var(--space-xs);
  max-inline-size: var(--measure);
}

.gallery-intro {
  margin-block-end: var(--space-2xl);
}

/* ---- services menu ------------------------------------------------------- */

/* The page is the shared .menu-layout (components.css): one column on a phone,
   intro left / menu right from 62rem up. It is not a bespoke grid here because
   the home page's services preview already composes exactly this way, and the two
   blocks have to read as one object.

   What this replaced: the menu was capped at 52rem inside a 74rem shell, so from
   1280px up 352px of the shell's content box - 30% of it - was permanently empty
   on the right while .shell (and with it the masthead, the nav and the language
   pill) still ran to the shell's edge. At 1920 that put the whole page in the
   left third of the screen with its own header overhanging it by 352px: measured
   shell.right - svcMenu.right was 0 / 0 / 80 / 180 / 352 / 352 / 352 / 352 px at
   360-1920. It is 0 at every one of those widths now. The cap also bought nothing
   it claimed to: leaders still measured 420-540px at 1440, which is the table
   rule the cap existed to prevent. Inside the second column they run ~200-410px. */
.svc-page {
  align-items: start;
}

@media (min-width: 62rem) {
  /* The masthead is sticky and 4.5rem tall, so the intro parks below it rather
     than under it. .menu-layout already sets align-items: start, which is what
     lets a sticky child move at all. */
  .svc-page .svc-intro {
    position: sticky;
    inset-block-start: calc(var(--header-h) + var(--space-lg));
  }
}

/* .menu__row is a one-column grid; the photo turns it into two. Sizes are fixed
   (not fluid) so every row in the column is identical and the price column stays
   in one vertical line down the page. */
.svc {
  grid-template-columns: 5rem minmax(0, 1fr);
  column-gap: var(--space-md);
  row-gap: 0;
  align-items: start;
}

@media (min-width: 48rem) {
  .svc {
    grid-template-columns: 7rem minmax(0, 1fr);
    column-gap: var(--space-lg);
  }
}

.svc__photo {
  align-self: start;
}

.svc__text {
  display: grid;
  gap: var(--space-xs);
  min-inline-size: 0;
}

/* A text link, not a third button tier: six outlined buttons down a price list is
   the card-grid look MENU-01 exists to prevent (CTA-01 keeps one primary). */
.svc__book {
  justify-self: start;
}

.svc-empty {
  max-inline-size: var(--measure);
}

/* ---- gallery grid -------------------------------------------------------- */
/* Same column rhythm as the home page's featured strip so the two read as one
   catalogue at two lengths. */

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-lg) var(--space-xs);
}

@media (min-width: 48rem) {
  .gallery-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-xl) var(--space-md);
  }
}

@media (min-width: 62rem) {
  .gallery-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.shot {
  display: grid;
  gap: var(--space-xs);
  align-content: start;
}

.shot__open {
  display: block;
  text-decoration: none;
  transition: opacity var(--dur-base) var(--ease-out);
}

.shot__open:hover {
  opacity: 0.88;
}

.shot__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs);
}

.shot__caption {
  min-inline-size: 0;
  color: var(--ink-soft);
  font-size: var(--step-small);
  line-height: 1.35;
}

.shot__open:hover + .shot__foot .shot__caption {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* ---- like button --------------------------------------------------------- */
/* A real <button> with aria-pressed, 44px in both directions (A11Y-03), and a
   tabular count so the row does not reflow by a pixel when 9 becomes 10. */

.like {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xs);
  min-inline-size: 2.75rem;
  min-block-size: 2.75rem;
  padding-inline: var(--space-xs);
  border-radius: var(--radius-pill);
  color: var(--ink-muted);
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  transition:
    color var(--dur-base) var(--ease-out),
    background-color var(--dur-base) var(--ease-out);
}

.like:hover {
  background-color: var(--plum-100);
  color: var(--blush-ink);
}

/* Pressed is carried by three things at once, never by colour alone: the heart
   fills, the ink darkens and aria-pressed flips. */
.like[aria-pressed="true"] {
  color: var(--blush-ink);
}

.like[aria-pressed="true"] .like__heart {
  fill: currentColor;
}

.like__heart {
  inline-size: 1.15em;
  block-size: 1.15em;
}

/* ---- lightbox ------------------------------------------------------------ */
/* The shell (overlay, panel, caption, controls) is components.css. What is added
   here is the frame: a square box sized from the viewport before the photo
   exists, so opening the dialog shifts nothing and moving between photos shifts
   nothing either — every source in this gallery is 1:1. */

/* A native <dialog> keeps the UA's width:fit-content / height:fit-content, and
   base.css's global `* { margin: 0 }` cancels the UA's margin:auto — so a dialog
   styled position:fixed; inset:0 still lays out as a content-sized box pinned to
   the top-left corner instead of covering the viewport. Pin it explicitly. */
.lightbox {
  inline-size: 100%;
  block-size: 100%;
  max-inline-size: 100%;
  max-block-size: 100%;
}

/* The frame is square and sized from the viewport, so the box exists at its final
   size before the photo does and moving between photos never resizes it.
   17rem is the rest of the dialog measured: the close button hanging 24px above
   the panel, the caption, the nav row, the CTA and the gaps between them, plus
   the dialog's own padding and ~26px of slack.

   There used to be a max(12rem, ...) floor under that calc, and the floor was the
   bug. Below ~29rem of viewport height the calc goes to nothing, the floor pinned
   the frame at 192px, and the panel therefore stayed a CONSTANT 366px tall no
   matter how short the viewport got — so the photo stopped giving up size and the
   controls gave it up instead. Measured (Enter-opened lightbox, book.bottom vs
   innerHeight): 667x375 the CTA was 15px off the bottom, 812x375 15px, 740x360
   30px, 640x320 70px, with close.top pinned at 0 at every one of them and
   scrolling to reach the CTA driving the close button off the top. The photo was
   also a 192px square inside a 667px-wide viewport — barely bigger than the tile
   it opened from, with 475px of unused width beside it.

   So: no floor (the photo shrinks, which is what the comment always claimed), and
   below 34rem of height in landscape the panel goes two-column and the photo is
   sized from the height it actually has. */
.lightbox__frame {
  display: grid;
  place-items: center;
  inline-size: min(100%, 46rem, calc(100svh - 17rem));
  aspect-ratio: 1;
  border-radius: var(--radius-photo);
  background: color-mix(in srgb, var(--paper) 10%, transparent);
}

.lightbox__frame .lightbox__img {
  inline-size: 100%;
  block-size: 100%;
  max-block-size: none;
  object-fit: contain;
}

/* base.css rings every control in --focus, which measures 8.1:1 on the page but
   only 1.5:1 against the lightbox's near-black overlay — invisible exactly where
   a keyboard user needs it most (A11Y-02 wants >=3:1 against the ADJACENT
   background). Inside the dialog the ring goes light: --paper on the overlay is
   11.8:1, and the 2px offset keeps it off the white control faces. */
.lightbox :focus-visible {
  outline-color: var(--paper);
}

.lightbox__position {
  color: var(--plum-300);
  font-size: var(--step--1);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The dialog's own controls sit on a near-black overlay, so the panel keeps the
   page's single primary treatment for the one action it offers. */
.lightbox__book {
  margin-block-start: var(--space-2xs);
}

/* A landscape phone has 640-915px of width and 320-414px of height. Stacking a
   square photo above a caption, a nav row and a CTA cannot fit in that; putting
   the photo beside them fits with room to spare, and the photo gets ~350px
   instead of 192px. Portrait is untouched — this is keyed to the shape of the
   viewport, not to a device. */
@media (orientation: landscape) and (max-height: 34rem) {
  .lightbox {
    padding: var(--space-sm) var(--space-md);
  }

  .lightbox__panel {
    grid-template-columns: auto minmax(13rem, 18rem);
    /* close, caption, nav, CTA — the photo spans all four. */
    grid-template-rows: auto auto auto auto;
    align-content: center;
    justify-items: start;
    gap: var(--space-xs) var(--space-lg);
    max-block-size: 100%;
  }

  /* Height first, so the photo is as big as the viewport allows; the third term
     only bites on a viewport too narrow to seat both columns (480x320 and the
     like), and there it keeps the controls on screen rather than the photo square. */
  .lightbox__frame {
    grid-column: 1;
    grid-row: 1 / -1;
    inline-size: auto;
    block-size: min(46rem, calc(100svh - var(--space-sm) * 2), calc(100svw - 17rem));
    max-inline-size: 100%;
  }

  /* No room above the panel for a hanging close button, so it takes the first row
     of the control column instead. */
  .lightbox__close {
    position: static;
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
  }

  .lightbox__caption {
    grid-column: 2;
    grid-row: 2;
    text-align: start;
  }

  .lightbox__nav {
    grid-column: 2;
    grid-row: 3;
  }

  .lightbox__book {
    grid-column: 2;
    grid-row: 4;
    margin-block-start: 0;
  }
}

/* Below the 48rem breakpoint the row is only ~250px wide once the photo has its
   column, which is too narrow to also park the duration beside the blurb. The
   blurb takes the full width and the duration drops under it as meta. */
@media (max-width: 47.99rem) {
  .svc .menu__foot {
    flex-wrap: wrap;
  }

  .svc .menu__blurb {
    flex: 1 1 100%;
  }

  .svc .menu__meta {
    text-align: start;
  }

  /* The leader is dropped on a phone, not shrunk. In a flex row it collapsed onto
     .menu__leader's 24px min-inline-size floor whenever the name wrapped, which
     put a ~10-glyph dotted fragment in mid-air beside the first line of a name
     that carried on below it — debris, not a rule joining a name to a price.
     Measured at 390px it hit the floor on "Set completo de acrílico" and "Arte
     pintado a mano", and Spanish names run long, so that is the common case in
     the primary locale. A two-column grid gives the name a column of its own and
     puts every price on one right axis; at this width the eye does not need a
     leader to travel 60px. It comes back at 48rem, where there is room for it. */
  .svc .menu__head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    column-gap: var(--space-md);
  }

  .svc .menu__leader {
    display: none;
  }
}
