/* ============================================================
   TrendiestStore — phone and tablet layer

   Loaded LAST (see snippets/ts-stylesheets.liquid), so it beats
   ts-tokens / ts-theme / ts-product / ts-glow on source order
   rather than on ever-longer selectors.

   1rem IS 12px HERE. `body_scale` is 120 and Dawn's root is
   `calc(body_scale/100 * 62.5%)`, so 1rem = 12px — not 16, and
   not Dawn's stock 10. Multiply by 12 before trusting any rem
   value. Lowering body_scale does not fix this, it makes it
   worse: at 100 the root is 10px.

   SEPARATELY, and this is the one that wastes an afternoon:
   `sizes` attributes are resolved by the preload scanner against
   16px whatever the page later says, so every `sizes` in this
   theme is written in PIXELS. Never put a rem in one.

   THE ONE THING THAT STILL BITES: a `stylesheet_tag` inside a
   SECTION body loads after everything in <head>, so it wins
   every equal-specificity tie against this file. Confirmed
   offenders — component-card.css, component-price.css,
   component-cart-items.css, quick-add.css,
   section-main-product.css, component-slider.css, and the
   `{% style %}` block in sections/header.liquid. Overrides
   against those carry an extra class on purpose.

   Breakpoints: 1200 / 989 / 749 / 620 / 420.
   ------------------------------------------------------------
   1  Grid counts          4  Product page
   2  Header + drawer      5  Cart, forms and footer
   3  Home sections        6  Overflow guards
   ============================================================ */

/* ---------- 1. Grid counts ----------------------------------- */
/* THESE MUST TARGET THE GRIDS, NOT `:root`.

   Each section writes its desktop count as an inline custom property on
   the grid element, and an inline declaration beats any stylesheet rule
   — including one inside a media query. Setting `--ts-cols` on `:root`
   here therefore did nothing at all: the phone rendered five product
   columns at 60px each. ts-glow.css reads the inline value once into
   `--cols`, and these re-declare `--cols` on the same elements, which is
   an ordinary rule against an ordinary rule and wins on source order.

   The phone value is 1 BY REQUIREMENT, not by taste: one product on
   screen at a time. */
@media screen and (max-width: 1200px) {
  .ts-products,
  .ts-collection .product-grid {
    --cols: 4;
  }
  .ts-cats {
    --cols: 4;
  }
}

@media screen and (max-width: 989px) {
  .ts-products,
  .ts-collection .product-grid {
    --cols: 3;
  }
  .ts-cats {
    --cols: 3;
  }
}

@media screen and (max-width: 749px) {
  .ts-products,
  .ts-collection .product-grid {
    --cols: 2;
  }
  .ts-cats {
    --cols: 2;
  }
}

@media screen and (max-width: 620px) {
  .ts-products,
  .ts-collection .product-grid {
    --cols: 1;
  }
  .ts-cats {
    --cols: 2;
  }
}

/* ---------- 2. Header + drawer ------------------------------- */
/* THE DRAWER IS THE ONLY NAVIGATION BELOW 990px, so everything here is
   load-bearing rather than cosmetic. The button that opens it is hidden
   by ts-glow.css — see the note on `.ts-burger` there for why that hide
   has to carry a min-width query and cannot be left unscoped. */
@media screen and (max-width: 1200px) {
  /* the header search pill goes; the drawer carries its own copy, and
     the icon in the tool cluster still reaches /search */
  .ts-nav__tools .ts-search {
    display: none;
  }
}

@media screen and (max-width: 989px) {
  .ts-nav__inner {
    min-height: 62px;
    gap: 12px;
  }

  /* the link row becomes a drawer.

     `visibility` and not `display`: a display:none panel cannot be
     transitioned, and the slide-down is what makes it read as a drawer
     coming out of the bar rather than a block appearing over the page.
     It is taken out of the tab order by `visibility: hidden` while
     closed, which `opacity: 0` alone would not do. */
  .ts-nav__menu {
    position: fixed;
    /* MEASURED, NOT `top: 100%` — AND THAT IS A BUG FIX, NOT A STYLE.
       This used to read `inset: 100% 0 auto` and leaned on `.ts-nav`
       carrying a `backdrop-filter`, which made the bar the containing
       block for its fixed children, so `100%` was the bar's own bottom
       edge. The 2026-09 re-skin sets `backdrop-filter: none` on the bar
       (ts-skin.css §7 and the inlined copy in ts-critical.css), and with
       the filter gone the containing block became the VIEWPORT: `top:
       100%` put the whole drawer one screen below the fold, so the
       burger opened a panel nobody could see. `--ts-bar-bottom` is
       written by ts-theme.js at the moment the drawer opens — the same
       value the scrim below already uses — so the panel hangs off the
       bar whatever the announcement strip is doing and whichever
       element happens to be the containing block. */
    inset: var(--ts-bar-bottom, 62px) 0 auto;
    z-index: 40;
    display: flex;
    visibility: hidden;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    /* --ts-bar-bottom is the bar's distance from the top of the
       viewport, written by ts-theme.js when the drawer opens. It moves
       — the announcement strip scrolls away and the bar sticks — and
       no CSS length can track that. */
    max-height: calc(100dvh - var(--ts-bar-bottom, 62px));
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 10px 18px 26px;
    background: var(--ts-nav-menu-bg);
    border-bottom: 1px solid var(--ts-line);
    border-radius: 0 0 22px 22px;
    box-shadow: 0 24px 48px -18px rgba(31, 27, 29, 0.28);
    opacity: 0;
    transform: translateY(-10px);
    transition: opacity 0.22s var(--ts-ease), transform 0.26s var(--ts-out),
      visibility 0s linear 0.26s;
  }

  .ts-nav[data-drawer='true'] .ts-nav__menu {
    visibility: visible;
    opacity: 1;
    transform: none;
    transition: opacity 0.22s var(--ts-ease), transform 0.26s var(--ts-out),
      visibility 0s;
  }

  /* The page behind the drawer, and what a tap-outside closes on — a
     document-level click handler cannot tell "outside the nav" from
     "on a link" reliably enough on touch.

     Z-INDEX 28, DELIBERATELY BELOW THE BAR'S 30. `.ts-nav` carries a
     `backdrop-filter`, which makes it a stacking context AND a
     containing block for fixed descendants, so the drawer's own
     z-index: 40 is scoped inside the bar and cannot be compared with a
     sibling's. Anything above 30 out here would paint over the drawer
     itself. Sitting under the bar is also why the scrim is a sibling
     and not a child: inside `.ts-nav` the same containing block would
     shrink `inset` down to the 62px-tall bar.

     `div.ts-scrim` AND NOT `.ts-scrim`: base.css hides every empty
     block element with `div:empty { display: none }`, and the scrim is
     by definition empty. A bare class is one specificity point short
     of that and the backdrop never painted. */
  div.ts-scrim {
    position: fixed;
    inset: var(--ts-bar-bottom, 62px) 0 0;
    z-index: 28;
    display: block;
    background: rgba(31, 27, 29, 0.34);
    backdrop-filter: blur(2px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.22s var(--ts-ease), visibility 0s linear 0.22s;
  }

  .ts-nav[data-drawer='true'] ~ .ts-scrim {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.22s var(--ts-ease), visibility 0s;
  }

  /* the drawer's own search pill, first thing under the bar */
  .ts-nav__searchrow {
    display: block;
  }

  .ts-drawer-search {
    display: flex;
    align-items: center;
    width: 100%;
    margin-bottom: 6px;
    padding: 4px 4px 4px 14px;
    border: 1px solid var(--ts-line);
    border-radius: var(--ts-r-pill);
    background: #fff;
  }

  .ts-drawer-search:focus-within {
    border-color: var(--ts-brand);
    box-shadow: 0 0 0 3px var(--ts-brand-wash);
  }

  .ts-drawer-search input {
    flex: 1 1 auto;
    min-width: 0;
    height: 34px;
    border: 0;
    outline: 0;
    background: transparent;
    font-family: inherit;
    font-size: 1.2rem;
    color: var(--ts-text);
  }

  .ts-drawer-search input::placeholder {
    color: var(--ts-muted-2);
  }

  .ts-drawer-search__go {
    flex: none;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: 50%;
    background: var(--ts-brand);
    color: #fff;
    cursor: pointer;
  }

  .ts-drawer-search__go svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.2;
    stroke-linecap: round;
  }

  .ts-nav__item {
    width: 100%;
  }

  .ts-nav__item + .ts-nav__item {
    border-top: 1px solid var(--ts-line);
  }

  .ts-nav__link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    width: 100%;
    /* 48px of tappable height, which the old 13px padding on a 1.2667rem
       line did not reach */
    min-height: 48px;
    padding: 12px 4px;
    border-bottom: 0;
    font-size: 1.2667rem;
    color: var(--ts-text);
    text-align: left;
  }

  .ts-nav__item--active > .ts-nav__link,
  .ts-nav__link[aria-expanded='true'] {
    color: var(--ts-brand);
  }

  /* the sliding underline is a desktop affordance */
  .ts-nav__link::after {
    display: none;
  }

  .ts-nav__caret {
    flex: none;
    width: 18px;
    height: 18px;
    color: var(--ts-muted-2);
  }

  /* The mega menu flattens into the drawer rather than floating, and
     collapses to nothing when its row is shut.

     MAX-HEIGHT AND NOT `grid-template-rows: 0fr`. The 0fr trick only
     collapses the tracks it is given, and `.ts-mega` has TWO children —
     the thumbnail list and the "View all …" link. The second one landed
     in an implicit `auto` row and stayed on screen under a 12px strip
     of the collapsed list's padding, which is exactly the "menu that is
     never really closed" look. Clipping the whole panel is unambiguous.

     The bound is generous on purpose: a menu that clips a category off
     the bottom is a bug, a close that finishes a shade early is not. */
  .ts-mega {
    position: static;
    display: block;
    width: auto;
    max-height: 0;
    overflow: hidden;
    transform: none;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
    opacity: 1;
    pointer-events: auto;
    transition: max-height 0.3s var(--ts-out);
  }

  .ts-nav__item[data-open='true'] .ts-mega {
    max-height: 1200px;
    animation: none;
  }

  /* the panel bridge that keeps a desktop hover alive has no business
     inside the drawer — it swallows taps meant for the row under it */
  .ts-mega::before {
    display: none;
  }

  .ts-mega__grid {
    grid-template-columns: 1fr;
    gap: 2px;
    margin-bottom: 10px;
    padding: 6px;
    border-radius: 16px;
    background: var(--ts-bg-2);
  }

  .ts-mega__link {
    gap: 12px;
    min-height: 44px;
    padding: 7px 10px;
    border-radius: 12px;
    font-size: 1.1667rem;
  }

  .ts-mega__thumb {
    width: 34px;
    height: 34px;
  }

  .ts-mega__all {
    margin: 0 6px 10px;
  }

  /* Given a wash of its own so it reads as a control rather than as
     decoration next to the filled cart pill — this is the ONLY way into
     the navigation below 990px, so it has to look like a button. */
  .ts-burger {
    display: grid;
    background: var(--ts-brand-wash);
    color: var(--ts-brand);
  }

  .ts-nav[data-drawer='true'] .ts-burger {
    background: var(--ts-brand);
    color: #fff;
  }

  .ts-nav__brand img {
    width: clamp(84px, 21vw, 104px);
  }
}

/* the page must not scroll behind an open drawer */
@media screen and (max-width: 989px) {
  html.ts-drawer-open,
  html.ts-drawer-open body {
    overflow: hidden;
  }
}

@media screen and (max-width: 420px) {
  /* the cart label drops, the pill keeps the icon and the count */
  .ts-cart-pill span.ts-cart-pill__label {
    display: none;
  }

  .ts-cart-pill {
    padding: 0 12px;
  }

  .ts-icon-btn {
    width: 36px;
    height: 36px;
  }
}

/* ---------- 3. Home sections --------------------------------- */
@media screen and (max-width: 989px) {
  /* hero: copy above, pack below, both centred */
  .ts-hero__grid {
    grid-template-columns: minmax(0, 1fr);
    text-align: center;
  }

  .ts-hero__sub {
    margin-inline: auto;
  }

  .ts-hero__actions,
  .ts-hero__stats {
    justify-content: center;
  }

  .ts-hero__seal {
    right: 12px;
    top: 12px;
  }

  /* four trust items do not fit a tablet row */
  .ts-trust__row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 0;
  }

  .ts-trust__item:nth-child(odd) {
    border-left: 0;
  }

  .ts-promo {
    grid-template-columns: minmax(0, 1fr);
  }

  .ts-promo__media img {
    max-height: 190px;
    object-position: center;
  }
}

@media screen and (max-width: 749px) {
  .ts-wrap,
  .ts-glow-wrap {
    padding-inline: 16px;
  }

  .ts-head {
    align-items: flex-end;
  }

  .ts-head__title {
    font-size: 1.6rem;
  }

  .ts-head__link {
    font-size: 1.0667rem;
  }

  /* stacked, so the seal shrinks and tucks into the corner above the
     pack rather than sitting on it.

     THE LABEL HAS TO SHRINK WITH THE CIRCLE. `1rem` is 12px here, so
     the desktop `span { font-size: 1rem }` stayed 12px inside a 62px
     disc: "Original Products" wrapped to two lines that each measured
     wider than the circle is at that height, and the words printed
     over the white edge onto the pack behind it. The disc gains a few
     px, the padding from ts-glow.css holds the text off the curve, and
     both lines are sized to fit the 56px that leaves. */
  .ts-hero__seal {
    width: 70px;
    padding: 7px;
    right: 10px;
    top: 10px;
    gap: 0;
  }

  .ts-hero__seal b {
    font-size: 1.2rem;
    line-height: 1.1;
  }

  .ts-hero__seal span {
    font-size: 0.7333rem;
    line-height: 1.15;
  }

  .ts-trust__row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    padding: 16px 10px;
  }

  .ts-trust__item {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding-inline: 10px;
  }

  .ts-trust__item + .ts-trust__item {
    border-left: 0;
  }

  .ts-trust__icon {
    width: 34px;
    height: 34px;
  }

  .ts-packs__rail {
    grid-auto-columns: minmax(180px, 76%);
  }

  .ts-foot__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .ts-foot__brand {
    grid-column: 1 / -1;
  }
}

@media screen and (max-width: 620px) {
  /* ONE PRODUCT PER ROW. The card is wide now, so it lays out
     side-by-side instead of growing a huge square image. */
  .ts-pcard {
    flex-direction: row;
    align-items: stretch;
  }

  .ts-pcard__media {
    flex: none;
    width: 40%;
    max-width: 168px;
    aspect-ratio: 1;
  }

  .ts-pcard__body {
    justify-content: center;
    padding: 12px 14px;
  }

  .ts-pcard__title {
    font-size: 1.2rem;
    -webkit-line-clamp: 3;
    line-clamp: 3;
  }

  .ts-pcard__price {
    font-size: 1.4rem;
  }

  .ts-pcard__add {
    margin-top: 8px;
    padding: 9px 12px;
  }

  .ts-cat__name {
    font-size: 1.0667rem;
  }
}

@media screen and (max-width: 420px) {
  .ts-hero__grid {
    padding-inline: 18px;
  }

  .ts-foot__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- 4. Product page ---------------------------------- */
@media screen and (max-width: 749px) {
  /* The stage is a square with `object-fit: contain`, but every studio
     photo is 3:4 portrait — so a 338px-wide square rendered the photo
     at 253px with 42px of white plate wasted down each side. Matching
     the stage to the photos lets them fill the width of the phone.
     Landscape cut-outs still letterbox inside the same box, which is
     the point of the fixed stage: switching thumbnails never reflows. */
  product-info .product__media-item .product-media-container {
    aspect-ratio: 3 / 4;
  }

  /* Dawn reserves the media drop-shadow's full reach under every slide —
     `max(--focus-outline-padding, --shadow-padding-bottom)`, which with
     this theme's shadow settings is 32px of empty space between the
     photo and the thumbnail rail. The shadow is at 10% opacity, so a
     shorter reservation loses nothing visible. (0,3,1) to clear the
     `.slider.slider--mobile .slider__slide` rule in component-slider.css. */
  product-info .slider.slider--mobile .product__media-item {
    padding-bottom: 20px;
  }

  product-info .product__info-wrapper {
    margin-top: 20px;
  }

  .product__title,
  .product__title h1 {
    font-size: 1.8667rem;
    line-height: 1.3;
  }

  /* the buy controls span the column on a phone */
  .product__info-container > variant-selects,
  .product__info-container > .product-form__quantity,
  .product__info-container > product-form,
  .product__info-container > .product-form,
  .product__info-container > .share-button,
  .product-form__buttons {
    max-width: 100%;
  }

  .product-form__submit,
  .shopify-payment-button__button {
    min-height: 52px;
    font-size: 1.3333rem;
  }

  /* the thumbnails are the whole navigation for 17 media on a phone,
     so they get a touch-sized tile */
  .thumbnail-list__item {
    width: 72px;
    max-width: 72px;
  }

  .thumbnail-list__item .thumbnail {
    height: 72px;
  }

  .ts-product__full {
    margin-top: 30px;
    padding-top: 24px;
  }

  .ts-product__full-body {
    font-size: 1.2667rem;
    line-height: 1.7;
  }
}

/* ---------- 5. Cart, forms and footer ------------------------ */
@media screen and (max-width: 749px) {
  .collection-hero__title,
  .main-page-title,
  .title--primary {
    font-size: 2.2667rem;
    line-height: 1.15;
    word-break: normal;
    overflow-wrap: anywhere;
  }

  /* inputs below 16px make iOS Safari zoom the whole page on focus and
     leave it zoomed — the classic "site is broken on my phone" report */
  .field__input,
  .select__select,
  .customer .field input,
  .quantity__input,
  textarea,
  input[type='text'],
  input[type='email'],
  input[type='tel'],
  input[type='search'],
  input[type='password'],
  input[type='number'] {
    font-size: 16px;
  }

  /* CART ROW.
     Dawn's phone cart is `repeat(2, auto) / repeat(4, 1fr)`, but the
     four tracks are not equal in practice: the thumbnail and the line
     total both have a wide min-content, so they take 100px each and
     squeeze the title into the two 49px tracks between them. A
     79-character product title in a 117px column wrapped to TEN lines
     and made the row 422px tall.

     Re-laid as [thumb | everything else], with the quantity stepper and
     the line total sharing the second row.

     component-cart-items.css loads from the cart section body, so each
     of these carries `.cart-items` to out-specify it rather than
     relying on source order. */
  .cart-items .cart-item {
    grid-template-columns: 96px minmax(0, 1fr) auto;
    gap: 14px;
    align-items: start;
  }

  .cart-items .cart-item__media {
    grid-column: 1;
    grid-row: 1 / 3;
  }

  .cart-items .cart-item__details {
    grid-column: 2 / 4;
    grid-row: 1;
  }

  .cart-items .cart-item__quantity {
    grid-column: 2;
    grid-row: 2;
  }

  .cart-items .cart-item__totals {
    grid-column: 3;
    grid-row: 2;
    align-items: center;
  }

  /* base.css sizes the stepper wider than the track it now sits in, so
     it spilled into the gap and butted against the line total. */
  .cart-item .quantity {
    width: 100%;
    min-width: 0;
  }

  /* the wrapper wraps on a phone, so the remove button starts a new line
     and Dawn's `margin-left: 1.3333rem` left it indented under nothing */
  .cart-item cart-remove-button {
    margin-left: 0;
    margin-top: 6px;
  }

  .cart-item .cart-item__name {
    font-size: 1.2267rem;
    line-height: 1.35;
  }

  .cart-item .cart-item__name,
  .cart-item .cart-item__details {
    overflow-wrap: anywhere;
  }

  .cart-item .cart-item__image {
    max-width: 100%;
    height: auto;
  }

  /* `.totals` is centred with an <h2> label, so "Estimated total" and
     the amount each wrapped onto two lines and sat on top of one
     another. Ends of the row, one line each. */
  .totals {
    justify-content: space-between;
    align-items: baseline;
    gap: 14px;
    flex-wrap: wrap;
  }

  .totals .totals__total {
    font-size: 1.3333rem;
    margin-top: 0;
  }

  .totals .totals__total-value {
    font-size: 1.5333rem;
    white-space: nowrap;
  }

  .footer__content-top {
    padding-bottom: 28px;
  }

  .footer-block__details-content .list-menu__item--link,
  .footer-block__details-content a {
    overflow-wrap: anywhere;
  }
}

/* ---------- 6. Overflow guards ------------------------------- */
/* Tables inside a rich-text description are the one thing that cannot
   be made to fit — give them their own scroller instead of letting them
   widen the page. */
@media screen and (max-width: 989px) {
  .rte table,
  .ts-product__full-body table,
  .metafield-rich_text_field table {
    display: block;
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
  }

  .rte img,
  .ts-product__full-body img {
    max-width: 100%;
    height: auto;
  }
}
