/**
 * Page-level responsive layout.
 *
 * Components size themselves with container queries in style.css; this file only deals
 * with the page skeleton, which genuinely depends on the viewport.
 *
 * The base styles in style.css are the mobile layout. Everything here is min-width, so
 * the narrowest supported width (320px) is what you get with no query matching at all.
 *
 * Tested at 320, 375, 390, 430, 768, 834, 1024, 1280, 1440, 1600 and 1920 - see
 * docs/TESTING.md.
 */

/* -------------------------------------------------------------------------- */
/* Small phones (base, up to 767px)                                            */
/* -------------------------------------------------------------------------- */

@media (max-width: 767px) {
  .site-nav {
    display: none;
  }

  /* The header row carries four things the client asked to keep: the lockup, the phone
     number, the Instagram icon and the menu. The lockup is the one that can give. At its
     desktop size the wordmark measures 124px, which left 4px of slack in the 328px shell
     of a 360px phone - a row that fits on paper and reads as jammed, with the number
     almost touching the trade line. Shrinking the logo by 16% frees ~20px, which is
     exactly what the gaps and the tap targets below need. Measured at 360. */
  .brand__wordmark {
    height: 1.85rem;
  }

  /* The trade line stays on a phone: the client asked for Elegant with "hemijsko
     ciscenje" under it, and hiding it left the wordmark alone. It tracks the wordmark
     down, because it is the wider of the two and would otherwise set the lockup width. */
  .brand__sub {
    display: block;
    font-size: 0.4rem;
  }

  .nav-toggle {
    display: inline-flex;
  }

  /* 6px rather than the 4px this row ran on while the logo was full size. Two circular
     buttons 4px apart read as one widget, and the first thing a thumb does with that is
     hit the wrong one. */
  .header-actions {
    gap: 0.375rem;
  }

  /* The gap between the lockup and the controls. The desktop 16px overflows a phone; 4px
     put the number against the trade line and the two read as one block of text. */
  .site-header__inner {
    gap: 0.375rem;
  }

  /* No hanger on a phone, hanger on desktop and laptop widths. The client's own
     correction: "ofinger ne treba da postoji na mobilnoj verziji u Logo-u. Na desktop
     i laptop sirinama treba da postoji ofinger". */
  .brand__mark {
    display: none;
  }

  /* Back to 44px, the size a thumb is actually tested against. These were cut to 40 to
     make the row fit at 360; the logo pays for it now instead. */
  .icon-link,
  .nav-toggle {
    width: 44px;
    height: 44px;
  }

  /* A 360px phone (Galaxy A, and most of the cheap Android fleet) is 15px narrower than
     the 375 this row was tuned on, and that was exactly the margin: the row ran 9px past
     its container and the page scrolled sideways. The number is the one thing in the
     header the client will not give up, so the button keeps its 16px text and loses the
     padding around it instead. Measured at 360: 9px over becomes 0. */
  .header-actions .btn--quiet {
    padding-inline: 0.5rem;
  }

  .header-actions .btn--primary {
    display: none;
  }

  .sticky-cta {
    display: flex;
  }

  /* Leave room for the sticky bar so it never covers the last element. */
  body {
    padding-bottom: 4.75rem;
  }

  .order__body {
    padding: var(--space-l) var(--space-m);
  }

  .order__foot {
    padding: var(--space-m);
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .order__foot .btn {
    width: 100%;
  }

  /* Four labels do not fit across 320px, so show progress as a bar plus a count. */
  .order__progress li {
    font-size: 0;
    padding: 0;
    height: 4px;
  }

  .order__progress li[data-state="current"] {
    background: var(--brand);
  }

  .order__progress li[data-state="done"] {
    background: color-mix(in oklch, var(--brand) 45%, var(--paper-sunken));
  }

  .pricing__controls {
    top: 4.5rem;
  }

  .item-row {
    grid-template-columns: 1fr auto;
    row-gap: var(--space-2xs);
  }

  .item-row__turnaround {
    grid-column: 1;
    grid-row: 2;
  }

  .item-row__actions {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--space-2xs);
  }

  .selected__row {
    grid-template-columns: 1fr auto;
    row-gap: var(--space-xs);
  }

  .selected__row .qty {
    grid-column: 1;
  }

  .selected__row .icon-btn {
    grid-column: 2;
    justify-self: end;
  }

  .footer__legal {
    flex-direction: column;
  }
}

/* Very narrow phones: 320px must not scroll sideways or clip a button. */
@media (max-width: 359px) {
  .shell,
  .shell--narrow {
    width: calc(100% - 1.5rem);
  }

  .btn {
    padding-inline: 1.1em;
  }

  .qty input {
    width: 2.6rem;
  }

  /* At 320px the wordmark, the phone number and the menu button together are wider than
     the content column, and the overflow shows up as the whole page scrolling sideways.
     The phone drops: it is in the sticky bar at the bottom of every screen, in the
     contact section and in the footer, so nothing is actually lost. */
  .header-actions .btn--quiet {
    display: none;
  }

  /* The wordmark used to shrink again here, to 1.4rem. That was paying for the phone
     number, and the rule above has just dropped it: with two 44px buttons the row is
     206px inside a 296px shell, so there is nothing left to buy and the logo stays the
     size it is on every other phone. */
}

/* -------------------------------------------------------------------------- */
/* Tablets and up (768px)                                                      */
/* -------------------------------------------------------------------------- */

@media (min-width: 768px) {
  /* The item picker is a long list. Keeping the running total and the "Dalje" button in
     view means the customer never has to scroll back to find out where they are.
     Desktop only: on mobile the fixed call/order bar already occupies the bottom edge. */
  .order__foot {
    position: sticky;
    bottom: 0;
    z-index: 5;
    background: color-mix(in oklch, var(--paper-raised) 94%, transparent);
    border-top: 1px solid var(--line);
    margin-top: calc(-1 * var(--space-m));
  }

  @supports (backdrop-filter: blur(1px)) {
    .order__foot {
      backdrop-filter: blur(10px);
    }
  }

  .steps {
    grid-template-columns: repeat(2, 1fr);
  }

  .cards {
    grid-template-columns: repeat(2, 1fr);
  }

  /* A landscape hero: the picture runs the full width of the screen and the type sits
     on it. There is no second column any more - the photograph that used to own the
     right-hand side has gone, which is what let the background become the hero instead
     of something peering around a card.

     The copy keeps to the left half so it stays over the part of the frame the wash
     holds at paper; the figures and the tradition line run the full width along the
     bottom, where the wash comes back to paper for them. Between those two the picture
     is open, which is the band the eye actually reads as "there is a photograph here". */
  .hero__inner {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    row-gap: var(--space-xl);
  }

  .hero__copy {
    /* Half the screen, capped, so the line length stays readable on a 27 inch monitor
       instead of running the headline across the whole frame. */
    max-width: min(52%, 40rem);
  }

  .hero__facts {
    grid-template-columns: repeat(3, 1fr);
  }

  .tiles {
    grid-template-columns: repeat(3, 1fr);
  }

  .plates {
    grid-template-columns: repeat(2, 1fr);
  }

  .field-grid--2 {
    grid-template-columns: 1fr 1fr;
  }

  .field-grid--3 {
    grid-template-columns: 2fr 1fr 1fr;
  }

  .choice-grid--3 {
    grid-template-columns: repeat(3, 1fr);
  }

  .footer-grid {
    grid-template-columns: 1.4fr 1fr 1fr;
  }
}

/* Between the tablet breakpoint and a comfortable laptop width the header cannot hold
   the brand lockup, five nav links, the phone number and the CTA at once: at 768px that
   row measured 817px inside a 721px shell and the whole document scrolled sideways.
   The nav is what gives, because every link in it is also in the menu panel, and the
   two things a visitor actually came for - call, or book - stay in the bar. The sticky
   bottom bar does not appear at this width, so the CTA has to survive here. */
@media (min-width: 768px) and (max-width: 1023px) {
  .site-nav {
    display: none;
  }

  .nav-toggle {
    display: inline-flex;
  }
}

/* -------------------------------------------------------------------------- */
/* Tablets and phones: the picture is a block, not a background                */
/* -------------------------------------------------------------------------- */

/* Below a laptop there is no second column to lay a landscape picture into - the text
   runs the full width - so the photograph stops being a background and becomes a block
   in the column, underneath the figures. The client's placement: headline, then the
   three numbers, then the picture.

   This has to reach 1023 rather than 767. A tablet is a single column too, and while
   this lived in the phone-only block an iPad got the desktop treatment: full-bleed
   picture with the copy running straight across the open half of it. */
@media (max-width: 1023px) {
  /* Source order is copy, picture, figures, tradition. Only the picture moves, so it is
     the only one that needs an order; the rest follow in source order around it. */
  .hero__facts {
    order: 1;
  }

  .hero__bg {
    order: 2;
    /* Out of the absolute layer and into the flow. `relative` rather than `static`,
       because the picture and the wash inside it are positioned against this box. */
    position: relative;
    z-index: auto;
    /* The asset is 16:9 and so is this box, which is the whole point: `cover` has
       nothing to crop, so the frame is shown entire. The client asked to see the whole
       photograph, and any other ratio here cuts something off it. */
    aspect-ratio: 16 / 9;
    /* Breaks the shell's gutters. A photograph with 16px of paper down each side reads
       as a card somebody pasted in rather than as part of the page.

       Done with the gutter, not with `100vw`. The usual `width: 100vw; margin-inline:
       calc(50% - 50vw)` counts the scrollbar as part of the viewport, so on any device
       with a classic one the picture comes out ~15px wider than the page and sits half
       that far off centre; the QA probe caught exactly that at 820px. The shell is
       `min(100% - 2rem, 76rem)`, and this block stops at 1023px - always below the point
       where the 76rem cap takes over - so the gutter here is always exactly 1rem a side.
       Cancelling it reaches the real page edge and nothing else. */
    margin-inline: -1rem;
    margin-block-start: var(--space-m);
  }

  /* The copy has the width to itself now, so the half-width cap from the desktop rules
     would just make the column needlessly narrow. The headline and the lede carry their
     own measure in ch, which is the limit that should apply here. */
  .hero__copy {
    max-width: none;
  }

  /* Nothing is written over this picture any more, so the wash has one job left: stop it
     arriving and leaving on two hard horizontal lines. Paper at both edges, fading out
     over a tenth of the height each way, so the photograph emerges from the page and
     dissolves back into it instead of being a band stuck on top of it. */
  .hero__veil {
    background: linear-gradient(
      to bottom,
      var(--paper) 0%,
      color-mix(in oklch, var(--paper) 62%, transparent) 4%,
      color-mix(in oklch, var(--paper) 18%, transparent) 10%,
      transparent 18%,
      transparent 82%,
      color-mix(in oklch, var(--paper) 18%, transparent) 90%,
      color-mix(in oklch, var(--paper) 62%, transparent) 96%,
      var(--paper) 100%
    );
  }

  /* Muted hard enough to sit behind a headline on the desktop, which is too far for a
     picture that is the subject here rather than the backdrop. */
  .hero__still,
  .hero__video {
    filter: saturate(0.9) brightness(1.02) contrast(0.98);
    /* Nothing is cropped at this ratio, so there is no side to favour. */
    object-position: 50% 50%;
  }
}

/* -------------------------------------------------------------------------- */
/* Small laptops (1024px)                                                      */
/* -------------------------------------------------------------------------- */

@media (min-width: 1024px) {

  .tiles {
    grid-template-columns: repeat(4, 1fr);
  }

  .plates {
    grid-template-columns: repeat(4, 1fr);
  }

  /* The even plates used to drop by 48px: an editorial stagger, so the row read as a
     composition rather than a filmstrip. It went, because it took the captions with it -
     the four of them sat on two baselines 24px apart and the strip read as ragged. That
     is what the client circled.

     Two fixes were tried before this one. Moving the offset onto the picture alone, with
     `.plates` owning two rows and each `.plate` borrowing them through subgrid, aligned
     the captions and then overflowed every picture 27px into them: the pictures are
     sized by `aspect-ratio` off their own width, so they do not shrink to fit a row, and
     a spanning subgrid item does not grow row one to take them. The captions ended up
     behind the photographs, which is worse than ragged.

     So the stagger is simply gone. One row, one baseline, nothing overlapping. A row of
     four equal plates is the plainer composition and it is the one that reads. */
  .steps {
    grid-template-columns: repeat(4, 1fr);
  }

  .cards {
    grid-template-columns: repeat(3, 1fr);
  }

  .footer-grid {
    grid-template-columns: 1.6fr 1fr 1fr 1fr;
  }

  /* On a pointer device the price list can run two columns and stay scannable. */
  .category__items {
    column-count: 2;
    column-gap: var(--space-2xl);
  }

  .item-row {
    break-inside: avoid;
  }
}

/* -------------------------------------------------------------------------- */
/* Desktop (1280px+)                                                           */
/* -------------------------------------------------------------------------- */

@media (min-width: 1280px) {
  :root {
    --measure: 66ch;
  }

  .order__body {
    padding: var(--space-2xl);
  }
}

/* Serbia is still desktop-majority, so wide screens get real layout attention
   rather than a stretched mobile view: the shell grows, the type does not. */
@media (min-width: 1600px) {
  .shell {
    width: min(100% - 4rem, 84rem);
  }

  .shell--narrow {
    width: min(100% - 4rem, 62rem);
  }
}

@media (min-width: 1920px) {
  .shell {
    width: min(100% - 6rem, 92rem);
  }
}

/* -------------------------------------------------------------------------- */
/* Print - customers do print the price list                                   */
/* -------------------------------------------------------------------------- */

@media print {
  .site-header,
  .sticky-cta,
  .pricing__controls,
  .order,
  .site-footer,
  .hero__actions,
  /* Photographs are the first thing to drop: someone printing this wants the prices,
     and a page of colour plates is a page of ink they did not ask for. */
  .hero__bg,
  .tiles,
  .plates,
  .band {
    display: none !important;
  }

  .category[open] .category__items,
  .category .category__items {
    display: block !important;
    column-count: 2;
  }

  body {
    background: #fff;
    color: #000;
    padding-bottom: 0;
  }

  .section {
    padding-block: 1rem;
    break-inside: avoid;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.75em;
    color: #555;
  }
}
