/* ==========================================================================
   The phone as an app.

   Everything here is inside one media query and, where it changes what the
   page shows rather than adds to it, behind html.app-on - the class app.js
   sets once it has built the screens. A desktop never reads a rule of this
   file; a phone without JavaScript gets the long page it always had.

   The viewport is the app's: the document does not scroll, the screens do,
   inside one fixed scroller (.app) that stops at the nav. So the browser's
   own bars never fold and unfold, the nav never jumps, and nothing can move
   the page sideways. The header scrolls away with the top of a screen - on
   the shop it lies over the hero card, as in the design.

   The reference: website_version_5/designv1-bg.png and nav bar design.png.
   Tokens are site.css's own (--ink, --surface, --gold, --accent, the three
   type families); glass is blur(20px) over rgb(10 10 10 / .75), as the
   design specifies. See docs/mobile-app.md.
   ========================================================================== */
.app-hero, .app-nav, .app-cta, .app-shop, .app-hdr-tag { display: none; }

@media (max-width: 940px) {
  :root {
    --app-nav-h: 72px;                 /* the floating nav pill */
    --app-nav-gap: 10px;               /* its distance from the bottom edge */
    --app-cta-h: 66px;                 /* the bar above it, gap included */
    --app-hdr-h: 68px;                 /* the header row */
    --app-gutter: 12px;                /* the screen's side margin */
    --app-glass: rgb(10 10 10 / .75);
    --app-card: rgb(var(--bone-rgb) / .035);
    --app-card-line: rgb(var(--bone-rgb) / .08);
    --app-radius: 26px;
  }

  /* ------------------------------------------------------------- frame -- */
  html.app-on, html.app-on body { height: 100%; overflow: hidden; overscroll-behavior: none; }
  html.app-on .app {
    position: fixed; left: 0; right: 0; top: 0; bottom: 0;
    overflow: hidden auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    background: var(--ink);
  }
  html.app-on .closing, html.app-on .closing__glow { display: none; }
  html.app-on .app-screen { display: none; }
  html.app-on .app-screen.is-on { display: block; }
  /* room under the content for the floating pills */
  html.app-on .app-screen { padding-bottom: calc(var(--app-nav-h) + var(--app-nav-gap) + 20px + env(safe-area-inset-bottom, 0px)); }
  html.app-on .app-screen--shop { padding-bottom: calc(var(--app-nav-h) + var(--app-nav-gap) + var(--app-cta-h) + 20px + env(safe-area-inset-bottom, 0px)); }
  html.app-on .app-cat { scroll-margin-top: 90px; }

  /* ------------------------------------------------------------ header -- */
  /* In the flow, at the top of the scroller: it goes with the first scroll.
     No ground of its own - on the shop it lies over the hero card. */
  html.app-on .hdr {
    position: relative; z-index: 3;
    background: transparent; border: 0; backdrop-filter: none; -webkit-backdrop-filter: none;
    padding: 0 calc(var(--app-gutter) + 8px);
  }
  html.app-on .hdr__in { height: var(--app-hdr-h); justify-content: space-between; padding: 0; gap: 12px; }
  html.app-on .hdr__nav, html.app-on .cartbtn { display: none !important; }
  /* The lockup: the mark on the left over both rows, the wordmark on the
     first row, the tag under it on the second. Every cell is placed by
     name, so the shape holds whether or not there is a mark - without one
     the tag used to slide into the mark's empty column and sit beside the
     word instead of under it. The word is sized for the name's length: two
     words of tracked capitals at the old 21px ran wider than the bar. */
  html.app-on .hdr__brand { display: grid; grid-template-columns: auto auto; grid-template-rows: auto auto; column-gap: 12px; row-gap: 3px; align-items: center; }
  html.app-on .hdr__mark { grid-column: 1; grid-row: 1 / 3; width: 40px; height: 40px; }
  html.app-on .hdr__word { grid-column: 2; grid-row: 1; font-size: clamp(14px, 4.4vw, 17px); letter-spacing: .2em; padding-left: 0; line-height: 1; align-self: end; }
  html.app-on .app-hdr-tag {
    display: block; grid-column: 2; grid-row: 2; align-self: start;
    font: 500 7.5px/1.35 var(--mono); letter-spacing: .24em; text-transform: uppercase;
    color: rgb(var(--gold-rgb) / .85); white-space: nowrap;
  }
  /* No mark yet: one column, the lockup starts at the edge. The mark's
     column comes back with the mark. */
  html.app-on .hdr__brand--text { grid-template-columns: auto; }
  html.app-on .hdr__brand--text .hdr__word, html.app-on .hdr__brand--text .app-hdr-tag { grid-column: 1; }
  html.app-on .acctbtn {
    width: 44px; height: 44px; padding: 0; justify-content: center; border-radius: 50%;
    background: rgb(var(--bone-rgb) / .08); border: 1px solid rgb(var(--bone-rgb) / .12);
    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
    color: #fff; flex: none;
  }
  html.app-on .acctbtn__t { display: none; }
  html.app-on .acctbtn svg { width: 18px; height: 18px; }

  /* -------------------------------------------------------------- hero -- */
  /* The design's hero: a card with rounded corners, inset from the edges,
     the photograph filling it, the header lying over its top. The desktop's
     two-column hero inside is put away, not restyled. */
  /* Edge to edge, as the design: the photograph fills the width, and the
     sheet that carries the shop rises over its foot with rounded corners. */
  html.app-on .hero {
    position: relative; z-index: 1;
    margin: calc(-1 * var(--app-hdr-h)) 0 0;
    min-height: min(132vw, 620px);
    overflow: hidden; isolation: isolate;
    /* the v5 phone plate stands its products in the middle, so it is shown
       from a little right of centre; 114% tall so the copy's top and the
       sheet's rise both land on picture */
    background: #06080A var(--app-hero-img) 45% 22% / auto 114% no-repeat;
    display: grid;
  }
  /* A narrow phone: the products move right - the plate is shown from its
     left edge and a little smaller - so the copy's column, the lede and the
     badges keep to the dark ground left of the cartridge; what the right
     edge loses is leaf. */
  @media (max-width: 400px) {
    html.app-on .hero { background-position: 0% 24%; background-size: auto 106%; }
    /* the three badges close up, so the third ends before the cartridge's foot */
    html.app-on .app-hero__badges { gap: 4px; }
    html.app-on .app-hero__badges li { width: 44px; }
    html.app-on .app-hero__ring { width: 30px; height: 30px; }
    html.app-on .app-hero__ring svg { width: 14px; height: 14px; }
  }
  html.app-on .hero .hero__bg, html.app-on .hero .hero__in { display: none; }
  html.app-on .hero::after { display: none; }   /* the desktop hero's water shade */
  html.app-on .hero::before {
    /* the copy's ground: the left third darkens, the bottom fades to the card */
    content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
    background:
      linear-gradient(to right, rgb(0 0 0 / .55), rgb(0 0 0 / .15) 55%, transparent 80%),
      linear-gradient(to bottom, rgb(0 0 0 / .35), transparent 30%, transparent 70%, rgb(0 0 0 / .55));
  }
  html.app-on .app-hero {
    position: relative; z-index: 1;
    display: grid; grid-template-rows: auto auto auto auto 1fr auto; align-content: start;
    padding: calc(var(--app-hdr-h) + min(13vw, 64px)) 20px 60px;   /* the sheet takes the last 30px */
    min-height: inherit;
  }
  .app-hero__eyebrow { display: none; }            /* the header's tagline says it */
  .app-hero__title {
    margin: 0 0 6px;
    /* 8vw, not 9.2: on a 360 screen "поколение." at 33px ran into the
       cartridge's mouthpiece; at 29px it stops short of it */
    font: 500 clamp(26px, 8vw, 42px)/.98 var(--display); letter-spacing: -.015em;
    color: #fff; max-width: 5.4em;                  /* two lines, left of the cartridge */
    text-shadow: 0 2px 28px rgb(0 0 0 / .6);
  }
  .app-hero__sub {
    margin: 0 0 18px;
    font: 500 clamp(17px, 4.8vw, 21px)/1.2 var(--display); letter-spacing: .01em;
    color: var(--gold-soft);
    text-shadow: 0 1px 14px rgb(0 0 0 / .7);
  }
  .app-hero__lede {
    margin: 0 0 18px;
    font: 500 10.5px/1.8 var(--mono); letter-spacing: .2em; text-transform: uppercase;
    color: rgb(var(--bone-rgb) / .8);
    text-shadow: 0 1px 12px rgb(0 0 0 / .7);
  }
  .app-hero__rule { display: block; width: 58px; height: 1.5px; background: var(--gold); }
  /* the three claims sit low, as in the design, with the aside across from them */
  .app-hero__badges {
    grid-row: 6; align-self: end;
    list-style: none; margin: 0; padding: 0;
    display: flex; gap: 5px; align-items: flex-start;
    width: max-content; max-width: 46%;
  }
  .app-hero__badges li {
    display: grid; justify-items: center; gap: 7px;
    width: 50px;
    font: 600 6.5px/1.35 var(--body); letter-spacing: .07em; text-transform: uppercase;
    text-align: center; color: rgb(var(--bone-rgb) / .92);
    text-shadow: 0 1px 10px rgb(0 0 0 / .8);
  }
  .app-hero__ring {
    width: 32px; height: 32px; border-radius: 50%;
    display: grid; place-items: center;
    border: 1.5px solid var(--gold); color: var(--gold);
    background: rgb(var(--ink-rgb) / .4);
    -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
    box-shadow: 0 0 18px rgb(var(--gold-rgb) / .18);
  }
  .app-hero__ring svg { width: 15px; height: 15px; }
  .app-hero__aside {
    position: absolute; right: 14px; bottom: 34px;
    margin: 0; text-align: right;
    font: 500 10px/1.7 var(--mono); letter-spacing: .22em; text-transform: uppercase;
    color: rgb(var(--bone-rgb) / .92);
    text-shadow: 0 1px 6px rgb(0 0 0 / .95), 0 0 18px rgb(0 0 0 / .9);
  }
  .app-hero__aside::after { content: ''; display: block; width: 48px; height: 1.5px; margin: 10px 0 0 auto; background: var(--gold); }

  /* -------------------------------------------------------------- shop -- */
  /* the sheet: the shop rises over the hero's foot on rounded corners */
  html.app-on .app-shop {
    display: block; position: relative; z-index: 2;
    margin-top: -30px; padding: 22px var(--app-gutter) 0;
    border-radius: 30px 30px 0 0;
    background: var(--ink);
    border-top: 1px solid rgb(var(--bone-rgb) / .08);
    box-shadow: 0 -16px 40px rgb(0 0 0 / .5);
  }
  html.app-on #vkusove, html.app-on #maslo { display: none; }   /* built anew below; their data lives on */

  /* The segmented control: a glass trough, a lit pill that glides between
     the two tabs, the products' own images on the tabs. */
  .app-tabs {
    position: relative; isolation: isolate;
    display: grid; grid-template-columns: 1fr 1fr;
    margin-top: 0; padding: 5px; border-radius: 999px;
    background: linear-gradient(180deg, rgb(var(--surface-rgb) / .92), rgb(var(--ink-rgb) / .96));
    border: 1px solid rgb(var(--bone-rgb) / .10);
    box-shadow: 0 16px 44px rgb(0 0 0 / .5), inset 0 1px 0 rgb(255 255 255 / .05);
  }
  .app-tabs__glide {
    position: absolute; top: 5px; bottom: 5px; left: 5px; width: calc(50% - 5px);
    border-radius: 999px; z-index: 0; will-change: transform;
    transition: opacity .25s var(--ease);
    background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 84%, #fff), color-mix(in srgb, var(--accent) 88%, #000));
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 55%, transparent), 0 10px 30px color-mix(in srgb, var(--accent) 38%, transparent), inset 0 1px 0 rgb(255 255 255 / .35);
  }
  .app-tab {
    position: relative; z-index: 1;
    display: inline-flex; align-items: center; justify-content: center; gap: 10px;
    min-height: 54px; padding: 0 12px; border: 0; border-radius: 999px;
    background: transparent; color: rgb(var(--bone-rgb) / .82);
    font: 600 16px/1 var(--body); letter-spacing: -.01em; cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color .25s var(--ease);
  }
  .app-tabs.is-none .app-tabs__glide { opacity: 0; transform: scale(.9); }
  .app-tab[aria-selected="true"] { color: var(--ink); }
  /* the shadows under the pictures are in the files (tools/bake-shadows.py):
     a drop-shadow filter is rendered again every time the element is
     rasterised, and the phone paid for the oil's on every swap into it */
  .app-tab__img { height: 34px; width: auto; display: block; flex: none; }
  .app-tab svg { width: 24px; height: 24px; flex: none; }
  .app-tab[aria-selected="true"] svg { filter: drop-shadow(0 1px 0 rgb(255 255 255 / .35)); }

  /* tall enough that any category - the oil's one card included - can
     scroll up until the tabs pin at the top */
  .app-cat { display: none; padding-top: 28px; min-height: 40vh; }
  .app-cat.is-on { display: block; }

  .app-h2 { margin: 0 0 4px; font: 500 clamp(30px, 8.6vw, 38px)/1.05 var(--display); color: #fff; letter-spacing: -.01em; font-variant-numeric: lining-nums; }
  .app-lede { margin: 0 0 20px; font: 400 15px/1.45 var(--body); color: rgb(var(--bone-rgb) / .62); }

  /* The two steps of the capsules: a numbered ring - the hero's own ring,
     gold - and the heading beside it, on one line, a hairline running on
     from it to the edge. One rhythm for both, on the 8px grid: 24px of air
     under a step to its control, twice that - 48px - above the second, so
     heading and control read as one block and the blocks as two. The
     chosen pack card stands 5px lifted, and the grid pays those back, so
     the card under the second step keeps the same 24px the stage keeps
     under the first. */
  .app-step {
    display: flex; align-items: center; gap: 14px;
    margin: 0 0 24px;
  }
  .app-step--2 { margin-top: 48px; }
  .app-step__n {
    flex: none; width: 34px; height: 34px; border-radius: 50%;
    display: grid; place-items: center;
    border: 1.5px solid var(--gold); color: var(--gold);
    background: rgb(var(--gold-rgb) / .08);
    box-shadow: 0 0 18px rgb(var(--gold-rgb) / .2), inset 0 1px 0 rgb(255 255 255 / .08);
    font: 600 14px/1 var(--mono); font-variant-numeric: lining-nums;
  }
  .app-step__t {
    font: 500 clamp(24px, 6.9vw, 30px)/1.1 var(--display); color: #fff; letter-spacing: -.01em;
    white-space: nowrap;
  }
  .app-step::after {
    content: ''; flex: 1 1 auto; height: 1px; margin-left: 4px;
    background: linear-gradient(90deg, rgb(var(--gold-rgb) / .45), rgb(var(--bone-rgb) / .06) 80%, transparent);
  }

  /* The packs: the capsules page's four cards, two to a row (site.css
     .pcards, .pcard - the ≤940 rules there set the columns). The lift and
     the gold ring are the card's own; a finger leaves no hover, so the
     hover's lift is not read here, or a card once tapped stood raised
     until the next tap somewhere else. */
  html.app-on .app-packs { margin-top: 0; padding-top: 5px; }
  @media (hover: none) {
    html.app-on .pcard:hover:not([aria-pressed="true"]) { transform: none; border-color: rgb(var(--bone-rgb) / .1); }
    html.app-on .pcard--pop:hover:not([aria-pressed="true"]) { border-color: rgb(var(--gold-rgb) / .4); }
    html.app-on .pcard:hover:not([aria-pressed="true"]) .pcard__art img { transform: none; }
    html.app-on .pcard:hover:not([aria-pressed="true"]) .pcard__art--10 img:nth-child(-n + 5) { transform: translateX(calc(var(--w) * .5 + 2px)) scale(.88); }
  }

  /* the stage: the renders, one at a time, a swipe apart */
  .app-stage {
    display: flex; gap: 14px;
    margin: 0 calc(-1 * var(--app-gutter)) 6px; padding: 0 12vw;
    overflow-x: auto; overflow-y: hidden; scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch; scrollbar-width: none; overscroll-behavior-x: contain;
  }
  .app-stage::-webkit-scrollbar { display: none; }
  .app-stage__i {
    flex: 0 0 76vw; aspect-ratio: 1; scroll-snap-align: center;
    border-radius: var(--app-radius); overflow: hidden;
    background: #000; border: 1px solid rgb(var(--bone-rgb) / .06);
    transform: scale(.925); opacity: .5;        /* app.js paints these every frame */
  }
  /* the shadow only under the render in the middle: the ones beside it are
     half transparent and their 50px blurs cost a frame each to raster */
  /* their own layers only while the stage is moving (app.js sets is-live) */
  .app-stage.is-live .app-stage__i { will-change: transform, opacity; }
  .app-stage__i.is-on { box-shadow: 0 22px 48px rgb(0 0 0 / .55), 0 0 0 1px rgb(var(--gold-rgb) / .18); }
  .app-stage__i { position: relative; }
  .app-stage__i img { width: 100%; height: 100%; object-fit: cover; display: block; }
  /* the way to the flavour's page, small, in the render's corner */
  .app-stage__more {
    position: absolute; right: 12px; bottom: 12px; z-index: 1;
    display: inline-flex; align-items: center; gap: 6px;
    min-height: 34px; padding: 0 12px 0 14px; border-radius: 999px;
    /* no backdrop blur: five of them sat inside the block being animated,
       each re-blurring what is under it on every frame of a swap */
    background: rgb(12 12 12 / .74); border: 1px solid rgb(var(--bone-rgb) / .18);
    color: #fff; font: 600 12px/1 var(--body); letter-spacing: .01em; text-decoration: none;
    box-shadow: 0 6px 18px rgb(0 0 0 / .4), inset 0 1px 0 rgb(255 255 255 / .12);
    -webkit-tap-highlight-color: transparent;
  }
  .app-stage__more i { font-style: normal; color: var(--accent); }

  /* the picker, as it was - the chips are site.css's; only their place changes */
  html.app-on .app-shop .picker { margin: 14px 0 0; }
  /* A finger leaves no hover, but a tap leaves :hover stuck on the chip
     until the next tap somewhere else - and site.css's hover looks like a
     choice, so a swipe to another flavour showed two chosen. Not here. */
  @media (hover: none) {
    html.app-on .chip:hover:not([aria-selected="true"]) {
      opacity: .68; filter: saturate(.65); color: rgb(var(--bone-rgb) / .88);
      border-color: transparent; background: transparent; box-shadow: none;
    }
  }

  /* the battery, one row: the accessory beside the cartridge. Never bought
     on its own - the control is a switch (site.css .sw), and while it is
     on the bar adds the battery together with the pack. The whole row is
     the switch's target, and it tints with it, so a glance says whether
     the battery is coming along. */
  .app-addon {
    display: flex; align-items: center; gap: 12px;
    margin-top: 16px; padding: 12px 14px 12px 12px; border-radius: 18px;
    background: var(--app-card); border: 1px solid var(--app-card-line);
    cursor: pointer; -webkit-tap-highlight-color: transparent;
    transition: border-color .25s var(--ease), background .25s var(--ease), transform .2s var(--ease);
  }
  .app-addon:active { transform: scale(.985); }
  .app-addon:has(.sw[aria-checked="true"]) {
    border-color: color-mix(in srgb, var(--accent) 45%, transparent);
    background: color-mix(in srgb, var(--accent) 6%, var(--app-card));
  }
  .app-addon__sw { display: inline-flex; align-items: center; gap: 10px; flex: none; }
  .app-addon img { width: 40px; height: 40px; object-fit: contain; flex: none; }
  .app-addon__t { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
  .app-addon__t b { font: 600 14.5px/1.2 var(--body); color: #fff; }
  .app-addon__t span { font: 500 12.5px/1.2 var(--mono); color: rgb(var(--bone-rgb) / .6); }
  /* a narrow phone: the word goes, the switch says it */
  @media (max-width: 360px) {
    .app-addon .sw-lbl { display: none; }
  }

  /* what customers say: every published review, newest first */
  .app-reviews { margin-top: 30px; }
  .app-reviews__h { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
  .app-h2--sm { font-size: clamp(24px, 6.6vw, 30px); margin: 0; }
  .app-reviews__sum { display: inline-flex; align-items: center; gap: 6px; margin: 0 0 4px; font: 600 13px/1 var(--body); color: var(--bone); white-space: nowrap; }
  .app-reviews__sum .stars svg { width: 13px; height: 13px; }
  .app-reviews__sum span { font-weight: 400; color: rgb(var(--bone-rgb) / .55); }
  .app-reviews__list { display: grid; gap: 10px; }
  .app-rv { padding: 16px 16px 14px; border-radius: 20px; background: var(--app-card); border: 1px solid var(--app-card-line);
    /* each review is laid out and painted only when scrolled near. The
       list begins on screen but runs far below it, and a swap used to pay
       for every review under the fold. */
    content-visibility: auto; contain-intrinsic-size: auto 150px;
  }
  .app-rv__top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; }
  .app-rv__top .stars svg { width: 14px; height: 14px; }
  .app-rv__ok { display: inline-flex; align-items: center; gap: 4px; font: 600 10.5px/1 var(--body); color: var(--accent); }
  .app-rv__ok svg { width: 11px; height: 11px; }
  .app-rv__t { margin: 0 0 4px; font: 600 15px/1.3 var(--body); color: #fff; }
  .app-rv__b { margin: 0 0 10px; font: 400 14.5px/1.5 var(--body); color: rgb(var(--bone-rgb) / .82); }
  .app-rv__by { margin: 0; font: 400 12.5px/1.3 var(--body); color: rgb(var(--bone-rgb) / .5); }
  .app-rv__by b { font-weight: 600; color: rgb(var(--bone-rgb) / .8); }

  /* the oil */
  .app-oil { position: relative; display: grid; grid-template-columns: 38% 1fr; gap: 16px; align-items: center; padding: 18px 18px 22px; border-radius: 22px; background: var(--app-card); border: 1px solid var(--app-card-line); }
  /* wider than its column by the shadow margin baked into the file, so the
     bottle keeps its size and the shadow falls into the gap beside it */
  .app-oil img { width: 117%; max-width: none; height: auto; display: block; margin-left: -8.5%; }
  .app-oil__name { margin: 0 0 4px; font: 500 clamp(24px, 6.4vw, 30px)/1.05 var(--display); color: #fff; }
  .app-oil__vol { margin: 0 0 10px; font: 500 11px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--gold); }
  .app-oil__price { margin: 0 0 8px; font: 700 22px/1 var(--body); color: #fff; }
  .app-oil__price s { font-weight: 500; font-size: 14px; color: rgb(var(--bone-rgb) / .45); margin-right: 8px; }
  .app-oil__meta { display: flex; align-items: center; gap: 8px; font: 600 12.5px/1 var(--body); color: rgb(var(--bone-rgb) / .8); }
  .app-oil__meta .stars svg { width: 14px; height: 14px; }
  .app-oil__desc { margin: 14px 0 0; grid-column: 1 / -1; font: 400 14.5px/1.55 var(--body); color: rgb(var(--bone-rgb) / .78); }
  /* the description: the product page's spread (partials/desc.php,
     site.css .desc), moved under the card and dressed like the card - the
     app's gutter instead of the page's, the card's corners, gold for the
     glow, since the oil has no flavour colour */
  html.app-on .app-oil-desc { --accent: var(--gold); padding: 0; margin: 12px 0 0; max-width: none; }
  html.app-on .app-oil-desc .desc { padding: 20px 16px 22px; border-radius: 22px; background: var(--app-card); border-color: var(--app-card-line); box-shadow: none; gap: 20px; }
  html.app-on .app-oil-desc .eyebrow { font-size: 11px; margin-bottom: 10px; }
  html.app-on .app-oil-desc .desc__lead { font-size: clamp(22px, 5.8vw, 27px); }
  html.app-on .app-oil-desc .prose { font-size: 15px; }
  html.app-on .app-oil-desc .pd__more-btn { background: rgb(var(--ink-rgb) / .9); }

  .app-shop__foot { margin: 22px 0 8px; text-align: center; font: 400 12.5px/1.5 var(--body); color: rgb(var(--bone-rgb) / .45); }

  /* ---------------------------------------------------------------- bar -- */
  /* One CTA for the whole shop screen: a floating pill above the nav's,
     where the thumb rests. In and out on a spring-like ease. */
  html.app-on .app-cta {
    position: fixed; left: var(--app-gutter); right: var(--app-gutter); z-index: 95;
    bottom: calc(var(--app-nav-h) + var(--app-nav-gap) + 10px + env(safe-area-inset-bottom, 0px));
    display: block;
    transform: translateY(calc(100% + var(--app-nav-h) + var(--app-nav-gap) + 30px)) scale(.96);
    opacity: 0;
    transition: transform .42s cubic-bezier(.32, 1.25, .5, 1), opacity .25s var(--ease);
    pointer-events: none;
  }
  html.app-on body.app-cta-on .app-cta { transform: none; opacity: 1; pointer-events: auto; }
  .app-cta__btn {
    position: relative; isolation: isolate; overflow: hidden;
    display: flex; align-items: center; justify-content: center; gap: 12px;
    width: 100%; min-height: 56px; padding: 0 20px; border: 0; border-radius: 999px;
    background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 84%, #fff), var(--accent));
    color: var(--ink); font: 700 16.5px/1 var(--body); letter-spacing: -.01em; cursor: pointer;
    box-shadow: 0 14px 40px color-mix(in srgb, var(--accent) 45%, transparent), 0 6px 18px rgb(0 0 0 / .45), inset 0 1px 0 rgb(255 255 255 / .38), inset 0 -1px 0 rgb(0 0 0 / .1);
    -webkit-tap-highlight-color: transparent;
    transition: filter .2s, box-shadow .25s;
  }
  .app-cta__btn svg { width: 22px; height: 22px; flex: none; }
  .app-cta__btn i { width: 1px; height: 18px; background: rgb(0 0 0 / .25); }
  .app-cta__t, .app-cta__busy, .app-cta__done { display: inline-flex; align-items: center; gap: 12px; }
  .app-cta__busy, .app-cta__done { position: absolute; inset: 0; justify-content: center; opacity: 0; transform: translateY(8px); transition: opacity .18s, transform .22s var(--ease); }
  .app-cta__busy b { width: 20px; height: 20px; border-radius: 50%; border: 2.5px solid rgb(0 0 0 / .2); border-top-color: var(--ink); animation: app-spin .8s linear infinite; }
  @keyframes app-spin { to { transform: rotate(360deg); } }
  .app-cta__btn.is-busy .app-cta__t, .app-cta__btn.is-done .app-cta__t { opacity: 0; transform: translateY(-8px); transition: opacity .14s, transform .2s var(--ease); }
  .app-cta__btn.is-busy .app-cta__busy, .app-cta__btn.is-done .app-cta__done { opacity: 1; transform: none; }
  .app-cta__btn.is-busy .app-cta__done { opacity: 0; }
  .app-cta__btn.is-done { background: linear-gradient(180deg, #4BE88A, #34E07A 60%); }
  .app-cta__btn:disabled { cursor: wait; }

  /* ---------------------------------------------------------------- nav -- */
  /* The design's floating pill: rounded ends, inset from the edges, dark
     glass with a light along its top, the cart raised in the middle on a
     ring with a green rim. The chosen item lifts and lights. */
  html.app-on .app-nav {
    position: fixed; left: var(--app-gutter); right: var(--app-gutter); z-index: 100;
    bottom: calc(var(--app-nav-gap) + env(safe-area-inset-bottom, 0px));
    height: var(--app-nav-h);
    display: grid; grid-template-columns: repeat(5, 1fr); align-items: end;
    padding: 0 6px; border-radius: 999px;
    background: linear-gradient(180deg, rgb(24 27 29 / .82), rgb(12 14 15 / .88));
    -webkit-backdrop-filter: blur(24px) saturate(1.3); backdrop-filter: blur(24px) saturate(1.3);
    border: 1px solid rgb(var(--bone-rgb) / .10);
    box-shadow: 0 22px 50px rgb(0 0 0 / .6), 0 2px 8px rgb(0 0 0 / .4), inset 0 1px 0 rgb(255 255 255 / .09), inset 0 -1px 0 rgb(0 0 0 / .35);
  }
  .app-nav__i {
    position: relative; display: grid; justify-items: center; align-content: end; gap: 6px;
    height: var(--app-nav-h); padding-bottom: 11px; border: 0; background: none;
    color: rgb(var(--bone-rgb) / .62); font: 500 9.5px/1.15 var(--body); text-align: center; letter-spacing: .01em;
    cursor: pointer; -webkit-tap-highlight-color: transparent; text-decoration: none;
    transition: color .28s var(--ease);
  }
  .app-nav__i > svg { width: 26px; height: 26px; transition: transform .38s cubic-bezier(.32, 1.4, .5, 1), filter .28s; }
  .app-nav__i[aria-current="true"] { color: var(--accent); }
  .app-nav__i[aria-current="true"] > svg { transform: translateY(-2px) scale(1.06); filter: drop-shadow(0 0 9px color-mix(in srgb, var(--accent) 60%, transparent)); }
  /* the dot under the chosen item, as iOS marks it */
  .app-nav__i::after {
    content: ''; position: absolute; left: 50%; bottom: 5px; width: 4px; height: 4px; border-radius: 50%;
    background: var(--accent); transform: translate(-50%, 4px) scale(0); opacity: 0;
    transition: transform .3s cubic-bezier(.32, 1.4, .5, 1), opacity .2s;
  }
  .app-nav__i[aria-current="true"]::after { transform: translate(-50%, 0) scale(1); opacity: 1; }
  .app-nav__i--cart::after { display: none; }
  .app-nav__ring {
    position: relative;
    width: 60px; height: 60px; border-radius: 50%;
    display: grid; place-items: center;
    background: radial-gradient(circle at 50% 24%, #1E2724, #0A0E0D 70%);
    border: 1.5px solid color-mix(in srgb, var(--accent) 62%, transparent);
    box-shadow: 0 0 0 5px rgb(12 14 15 / .95), 0 10px 26px rgb(0 0 0 / .55), 0 0 30px color-mix(in srgb, var(--accent) 40%, transparent), inset 0 1px 0 rgb(255 255 255 / .1), inset 0 -6px 14px rgb(0 0 0 / .4);
    color: #fff;
    transform: translateY(-9px);
    transition: box-shadow .3s;
  }
  .app-nav__ring > svg { width: 26px; height: 26px; }
  .app-nav__badge {
    position: absolute; top: 5px; right: -8px;      /* beside the ring's shoulder, under the bar's words */
    min-width: 20px; height: 20px; padding: 0 5px; border-radius: 999px;
    display: grid; place-items: center;
    background: var(--accent); color: var(--ink); font: 700 10.5px/1 var(--body);
    box-shadow: 0 0 0 2px #0B0F0E, 0 4px 10px rgb(0 0 0 / .4);
  }
  .app-nav__badge[hidden] { display: none; }
  .app-nav__i--cart span:last-child { margin-top: -4px; }

  /* the cart drawer: app.js moves it on springs; the stylesheet's own
     transitions would fight them */
  /* Vertical pans are the browser's, the sideways swipe is app.js's. On the
     scrollers themselves, not only the drawer: a touch inside a scroller is
     judged by the scroller's own touch-action, and the drawer's above it
     is never consulted. */
  html.app-on .cart, html.app-on .cart__top, html.app-on .cart__split, html.app-on .cart__main,
  html.app-on .cart__body, html.app-on .cart__side, html.app-on .cart__foot { touch-action: pan-y; }
  html.app-on .cart { transition: none; width: 100%; border-left: 0; }
  html.app-on .cart__scrim { transition: none; }
  /* the sum: the euro large, the lev on its own line beneath, never a
     figure broken in the middle; the label small and quiet */
  html.app-on .sumcard { padding: 16px 18px; border-radius: 20px; }
  html.app-on .tot { font-size: 14.5px; }
  html.app-on .tot--big { align-items: flex-start; margin-top: 12px; padding-top: 14px; }
  html.app-on .tot--big > span:first-child { padding-top: 7px; font: 600 11.5px/1 var(--mono); letter-spacing: .16em; color: rgb(var(--bone-rgb) / .6); }
  html.app-on #cart-sub { display: grid; justify-items: end; gap: 3px; font-size: 24px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap; text-align: right; }
  html.app-on .tot__alt { display: block; font: 500 12.5px/1.2 var(--mono); color: var(--muted); }
  /* the lines: the picture whole and a size larger, the words to match */
  html.app-on .li { grid-template-columns: 76px minmax(0, 1fr); gap: 14px; padding: 12px; border-radius: 20px; }
  html.app-on .li__img { width: 76px; height: 76px; border-radius: 16px; object-fit: cover; }
  html.app-on .li__n { font-size: 17px; font-weight: 600; }
  html.app-on .li__p { font-size: 13.5px; margin-top: 4px; }
  html.app-on .li .li__save { margin-top: 6px; font-size: 12px; padding: 4px 10px; }
  html.app-on .li__now { font-size: 20px; }
  html.app-on .li__was { font-size: 13px; }
  /* the way to the checkout: the same pill as the shop's bar */
  html.app-on .cart__foot .glowring { margin-top: 4px; }
  html.app-on .cart__foot .btn--apple.btn--wide { min-height: 56px; font-size: 16.5px; font-weight: 700; }
  html.app-on .cart__cont { margin-top: 8px; min-height: 46px; font-size: 14px; color: rgb(var(--bone-rgb) / .62); }

  /* the cookie banner keeps clear of the nav */
  html.app-on .cc { bottom: calc(var(--app-nav-h) + var(--app-nav-gap) + env(safe-area-inset-bottom, 0px) + 8px); }

  /* ---------------------------------------------------------- screens -- */
  html.app-on .app-screen--docs .band, html.app-on .app-screen--ask .band { padding-block: var(--s6); }
  html.app-on .app-screen--ask .ask { margin: 0 0 var(--s6); }
  html.app-on .app-screen--ask .ftr { padding-bottom: var(--s5); }

  @media (prefers-reduced-motion: reduce) {
    .app-stage__i, .app-cta, .app-tab, .app-addon { transition: none; }
  }
}
