/*
 * NICO Boulangerie - the ordering flow: basket, checkout, review.
 *
 * ---------------------------------------------------------------------------------------------
 * WHY THIS IS NOT IN site.css.
 *
 * site.css is linked by every page on the site, render-blocking, and the rules below apply to
 * exactly three of them. A two-column order shell, a sticky summary panel and a three-step
 * indicator are worth nothing to the home page, the catalogue or a legal page, and they are the
 * kind of layout that only grows. layout/base.php's `$pageStyles` hook exists for precisely this:
 * a view opts in by name, and only the pages that need these rules pay for them.
 *
 * Nothing here restates site.css. Every colour, radius, font and measure below resolves through a
 * token declared there - `--nico-accent`, `--nico-border`, `--nico-ink-muted` and the rest - so
 * this file cannot drift into a second palette. It adds classes; it overrides none.
 * ---------------------------------------------------------------------------------------------
 *
 * PORTO IS A COMPONENT LIBRARY HERE, NOT A SKIN. The structure is lifted from Porto 13.1.0's
 * shop-cart.html and shop-checkout.html - the wide line table beside a narrow bordered summary
 * card, the card's small uppercase title, the line-with-quantity list inside it, the totals stack,
 * and the full-width call to action at its foot. None of Porto's CSS, none of its markup classes
 * and none of its JavaScript is imported: its sticky panel is a jQuery plugin
 * (`data-plugin-sticky`) and its quantity stepper is a jQuery handler, and both are replaced here
 * by CSS that needs no script at all.
 *
 * THE WHOLE ORDERING FLOW SHIPS ZERO JAVASCRIPT, like the rest of src/Public. That is a
 * reliability decision: this bakery's customers order from phones on Gili Air, where a script is
 * the thing that fails. So `position: sticky` does the panel, a grid does the collapse, and every
 * control on all three pages is a form that posts.
 */

/* ---------------------------------------------------------------- the two-column shell */

/*
 * The order shell: the work on the left, the money on the right.
 *
 * ONE COLUMN UNTIL 62em, which is site.css's own desktop breakpoint - the same one the header and
 * the section grids turn at. A second breakpoint invented here would put the order pages out of
 * step with every other page at one width, which is the sort of thing nobody notices until a
 * screenshot lands on a phone that happens to be exactly that wide.
 *
 * `minmax(0, 1fr)` on the main column, not `1fr`. A grid track's default minimum is its content's
 * own minimum, and the content here is a table of product names and money that refuses to wrap -
 * so a plain `1fr` lets the widest row push the whole grid past the viewport and scroll the PAGE
 * sideways. With the minimum pinned at 0 the track is free to be narrower than its table, and
 * `.nico-table-wrap` does the scrolling it already knows how to do, inside its own box.
 */
.nico-shop {
  display: grid;
  /*
   * THE SINGLE COLUMN IS DECLARED rather than left implicit.
   *
   * A grid with no `grid-template-columns` drops its items into an IMPLICIT track sized `auto`,
   * and `auto` can resolve to the widest item's max-content. The item here is a table of product
   * names and money that refuse to wrap - 813px of it at 390px viewport - so the track's floor is
   * worth pinning rather than relying on the container's definite width to hold it down.
   *
   * `minmax(0, 1fr)` states that floor at every width. The two-column rule below overrides it, and
   * the `min-width: 0` on the items covers the other half of the same hazard: a track pinned at 0
   * still overflows if the item sitting in it is not.
   */
  grid-template-columns: minmax(0, 1fr);
  gap: 1.75rem;
  margin-top: 1.5rem;
}

.nico-shop__main,
.nico-shop__aside {
  /* Both tracks, because a grid item's default `min-width: auto` is what actually leaks the
     overflow - pinning the track alone is not enough once the item inside it is a table. */
  min-width: 0;
}

@media (min-width: 62em) {
  .nico-shop {
    /*
     * HOW FAR BELOW THE VIEWPORT'S TOP THE STICKY PANEL COMES TO REST.
     *
     * `.nico-header` is `position: sticky; top: 0`, so a panel resting at 0 slides UNDER it and
     * loses its title behind the logo. This first shipped as a hand-measured 8rem, which was 23px
     * short of the real header and only showed up once the page was actually scrolled.
     *
     * `--nico-header-height` in site.css is now composed from the four values that decide the
     * header's height, and the header consumes those same values - so this offset cannot drift
     * from it. The half-rem is the air between the two; it is the only number here that is a
     * judgement rather than a measurement.
     */
    --nico-shop-sticky-top: calc(var(--nico-header-height) + 0.5rem);

    grid-template-columns: minmax(0, 1fr) 21rem;
    gap: 2.25rem;
    align-items: start;
  }

  /*
   * ON A BARE-CHROME PAGE THERE IS NOTHING AT THE TOP TO CLEAR, so the panel rests on the air alone.
   *
   * The checkout and the review carry no site header at all - see `$bareChrome` in
   * layout/base.php - and partials/bare_head.php is deliberately NOT sticky, so the offset above
   * would hold the panel 124px down the viewport with an empty strip over it. The half-rem is the
   * same judgement the line above makes; what is dropped is the measurement of a header that is not
   * there.
   *
   * THE BASKET KEEPS THE FULL OFFSET. /cart draws the same `.nico-shop` grid under the real header,
   * which is why this is scoped to the plate's modifier rather than written into the rule above.
   */
  .nico-page--bare .nico-shop {
    --nico-shop-sticky-top: 0.5rem;
  }

  /* `align-self: start` is what makes the sticky work at all. A grid item stretches to its row's
     full height by default, and an element that is already as tall as its container has nothing
     to stick within - `position: sticky` on it is silently inert. */
  .nico-shop__aside {
    position: sticky;
    top: var(--nico-shop-sticky-top);
    align-self: start;
  }
}

/* ---------------------------------------------------------------- the summary panel */

/*
 * Porto's "CART TOTALS" and "YOUR ORDER" card: a heavy border, no fill, and the figures stacked
 * inside it. Porto sets its cards square-cornered with a 3px rule; this one keeps the site's own
 * radius and steps the border down to 2px, because every other bordered box on this site
 * - `.nico-table-wrap`, the legal tables, the account panels - is a 1px hairline at
 * `--nico-radius-lg`, and a square 3px card among them reads as a component from another site.
 * Two pixels is enough to say "this one is different" without saying "this one is foreign".
 */
.nico-shop-panel {
  padding: 1.35rem;
  border: 2px solid var(--nico-ink);
  border-radius: var(--nico-radius-lg);
  background-color: var(--nico-white);
}

/* The card's title, in the same small uppercase treatment `.nico-price-table thead th` already
   uses for a column heading. That is deliberate: both are labels over a stack of figures, and
   giving the panel its own heading style would be a second answer to one question. */
.nico-shop-panel__title {
  margin: 0 0 0.9rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--nico-ink-muted);
}

/* A sentence inside the panel - what a guest is told instead of a price, or why a total is
   missing. Set at the panel's own reading size rather than as fine print: it is the content of
   the panel in that state, not a footnote to it. */
.nico-shop-panel__note {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--nico-ink-muted);
}

.nico-shop-panel__note:last-child {
  margin-bottom: 0;
}

/*
 * The order's lines inside the panel: what, how many, and what that comes to.
 *
 * Porto sets these as table rows; a list is the honest element - they are items, not a grid of
 * related figures, and the panel is too narrow for a table's columns to survive a long product
 * name anyway.
 */
.nico-shop-panel__lines {
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
  font-size: 0.9rem;
}

.nico-shop-panel__lines li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.85rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--nico-border);
}

.nico-shop-panel__lines li:first-child {
  padding-top: 0;
}

/* `min-width: 0` so a long product name can wrap inside the flex row instead of forcing the row
   wider than the panel and pushing the money off its edge. */
.nico-shop-panel__line-name {
  min-width: 0;
  color: var(--nico-ink);
}

/* The quantity, riding with the name rather than in a column of its own - Porto's "x1". Muted,
   because it qualifies the product; the two figures that matter in this panel are the line total
   and the total. */
.nico-shop-panel__line-qty {
  color: var(--nico-ink-muted);
  white-space: nowrap;
}

/* The pack, ON THE SAME LINE as the name rather than folded under it. A product name alone is
   ambiguous here in a way it is not in the table beside it, where Pack has its own column - but
   "Baguette" and the pack it comes in are one thing being ordered, and splitting them over two
   lines made a one-line basket read as two. Inline, muted and a size down, so it still reads as a
   qualifier of the name and not as a second product. */
.nico-shop-panel__line-pack {
  display: inline;
  margin-left: 0.35rem;
  font-size: 0.8rem;
  color: var(--nico-ink-muted);
}

.nico-shop-panel__line-total {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* A line the quote could not price. The dash is already the honest answer in the table; here it
   is muted as well, so it does not read as a figure. */
.nico-shop-panel__line-total--none {
  color: var(--nico-ink-muted);
}

/*
 * `.nico-summary` is site.css's totals block and it is reused here unchanged, because the figures
 * in this panel are the same figures in the same order as the ones the basket used to print under
 * its table. Only its placement changes: inside a 21rem card, its `margin-left: auto` and 22rem
 * cap have nothing left to do, so they are released here rather than the block being rewritten.
 */
.nico-shop-panel .nico-summary {
  margin: 0;
  max-width: none;
}

/* Where the panel's figures end and its action begins. */
.nico-shop-panel__actions {
  margin-top: 1.15rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

/* Porto's full-width call to action. Every button in this stack spans the card, so the primary one
   cannot be mistaken for one of a row of equals - which is what happened when these lived in a
   `.nico-btn-row` under the table and "Empty basket" sat the same width as "Continue to
   checkout". */
.nico-shop-panel__actions .nico-btn {
  width: 100%;
  justify-content: center;
}

/* The form wrapper around a button that has to post - emptying the basket, confirming the order.
   It exists only to carry the token, so it must not introduce a width of its own. */
.nico-shop-panel__actions form {
  display: contents;
}

/* The panel's "how it arrives" facts list is GONE, and so are the four rules that dressed it. It
   named the method above a totals row that named it again with the price beside it, and the owner's
   ruling is one line for both - the method is now that row's own label. Deleted rather than left in
   place: a selector nothing emits is a block the next person styles for a row that will never
   render. */

/* ---------------------------------------------------------------- the delivery schedule */

/*
 * THE DAYS WE COME TO AN AREA, under the checkout's date field.
 *
 * A quiet inset rather than a table: the account dashboard's own tile is a list of day chips and
 * this is the same fact in a narrower column, so it borrows that shape rather than inventing a grid.
 * It is READ-ONLY and never looks like a control - a native date input cannot exclude weekdays, so
 * anything here that read as pressable would promise a filter the browser cannot apply.
 */
.nico-schedule {
  margin-top: 0.75rem;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--nico-border);
  border-radius: var(--nico-radius);
  background-color: var(--nico-light);
}

.nico-schedule__head {
  margin: 0;
  color: var(--nico-ink-muted);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* The served days, as a row of chips that wraps on a narrow screen. It is a `<ul>` when there are
   days to list and a `<p>` when the answer is the single words "Every day", so both element types
   carry the rule and the list drops its bullets and its indent. */
.nico-schedule__days {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0.45rem 0 0;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
  font-weight: 600;
}

.nico-schedule__days li {
  padding: 0.1rem 0.45rem;
  border-radius: var(--nico-radius);
  background-color: var(--nico-accent-soft);
}

.nico-schedule__note {
  margin: 0.45rem 0 0;
  color: var(--nico-ink-muted);
  font-size: 0.8rem;
  line-height: 1.5;
}

/* ---------------------------------------------------------------- the step indicator */

/*
 * Basket -> Checkout -> Review, as three numbered steps rather than the bare "Step 2 of 3" kicker
 * these pages carried before.
 *
 * AN ORDERED LIST, because that is what it is: three stages in a fixed order, and a screen reader
 * announcing "list of 3 items" is telling the truth about the page. The current one is marked
 * `aria-current="step"` in the markup, which is what a reader hears; the styling below is the
 * sighted half of the same fact and never the only half.
 *
 * A STEP ALREADY PASSED IS A LINK and a step not reached yet is plain text. That is not decoration
 * either - going back to the basket from the checkout is a real thing a customer does, and the
 * three-step strip is where they will look for it.
 */
.nico-steps-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.35rem;
  margin: 0 0 1.5rem;
  padding: 0;
  list-style: none;
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.nico-steps-bar__step {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--nico-ink-muted);
}

/* The rule between one step and the next. A pseudo-element rather than a character in the markup,
   so no screen reader reads out an arrow between two list items it has already numbered. */
.nico-steps-bar__step + .nico-steps-bar__step::before {
  content: '';
  width: 1.35rem;
  height: 1px;
  margin-right: 0.35rem;
  background-color: var(--nico-border);
}

/* The numbered disc. Sized in `em` so it tracks the strip's own font size rather than being pinned
   to a pixel count that stops matching the moment the type scale moves. */
.nico-steps-bar__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.85em;
  height: 1.85em;
  flex: 0 0 auto;
  border: 1px solid var(--nico-border);
  border-radius: 50%;
  font-size: 0.85em;
  font-weight: 700;
  letter-spacing: 0;
  color: var(--nico-ink-muted);
  background-color: var(--nico-white);
}

/* The step being filled in now. Filled disc AND heavier ink on the name - two signals, because a
   colour-only difference is invisible to a reader who cannot separate these two greys, and this
   strip's whole job is to say which of three pages you are on. */
.nico-steps-bar__step[aria-current='step'] {
  color: var(--nico-ink);
  font-weight: 700;
}

.nico-steps-bar__step[aria-current='step'] .nico-steps-bar__num {
  border-color: var(--nico-band-accent);
  background-color: var(--nico-band-accent);
  color: var(--nico-white);
}

/* A step already completed. Its disc keeps the accent as an outline - the work is done, but the
   page is no longer here. */
.nico-steps-bar__step--done .nico-steps-bar__num {
  border-color: var(--nico-band-accent);
  color: var(--nico-accent-dark);
}

/* A completed step's link wraps BOTH its disc and its name - see partials/steps_bar.php for why -
   so it has to lay them out the way the unlinked step's `<li>` does. Same direction, same gap, so
   a done step and a current one sit on one baseline rather than stepping apart at the one width
   where they are neighbours. */
.nico-steps-bar__step a {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: inherit;
  text-decoration: none;
}

.nico-steps-bar__step a:hover,
.nico-steps-bar__step a:focus-visible {
  color: var(--nico-ink);
  text-decoration: underline;
}

/* ---------------------------------------------------------------- the basket table */

/*
 * The product thumbnail column, lifted from Porto's cart.
 *
 * FIXED SQUARE, and the image is cropped into it rather than fitted. Product photography arrives
 * at whatever shape it was shot in, and a column whose rows are each a different height turns a
 * five-line basket into a page of ragged bands.
 */
.nico-cart__thumb {
  width: 4.5rem;
  height: 4.5rem;
  overflow: hidden;
  border: 1px solid var(--nico-border);
  border-radius: var(--nico-radius);
  background-color: var(--nico-light);
}

.nico-cart__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * The tile a row gets when the product carries no photograph.
 *
 * A NEUTRAL SURFACE, not a broken-image icon and not the word "no image". A missing photo is our
 * gap in the catalogue, not a fault in the customer's order, and a column of apology icons down
 * the side of a basket makes the order look wrong when nothing about it is.
 */
.nico-cart__thumb--empty {
  background-image: linear-gradient(135deg, var(--nico-accent-soft) 0%, var(--nico-light) 100%);
}

/* The cart's first column holds a fixed-width tile and nothing else, so it takes only the width it
   needs and leaves the rest to the product name. */
.nico-cart td.nico-cart__thumb-cell {
  width: 1%;
  padding-right: 0;
}

/* The pack, ON THE SAME LINE as the product name - Porto puts the variant there and it is the
   same relationship. It still holds no column of its own, which is what buys the space the
   thumbnail takes; what changed is that it rides beside the name instead of under it, so a basket
   line is one line. Muted and a size down, so it reads as a qualifier rather than a second name. */
.nico-cart__pack {
  display: inline;
  margin-left: 0.35rem;
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--nico-ink-muted);
  white-space: normal;
}

/* A product name is the one cell in this table that must be allowed to wrap. `.nico-price-table`
   sets `white-space: nowrap` on every cell, which is right for money and pack counts and wrong for
   "Pain de Campagne au Levain", whose row would otherwise be as wide as the sentence. */
.nico-cart th[scope='row'] {
  white-space: normal;
  min-width: 11rem;
}

/* ---------------------------------------------------------------- the mobile total */

/*
 * THE CHECKOUT'S SUMMARY BELOW 62em: one collapsed card above the buttons, holding the same lines
 * and totals the wide layout's aside prints.
 *
 * Under 62em the aside would sit BELOW the form, so the primary submit would be the first of the
 * two a customer reaches and they would be committing without having seen a figure - and, printed
 * in full, it doubled the page's summary. The card's closed state is one row (label, the same
 * `grand_total` the aside prints, a caret); opening it shows the rest. The aside is hidden at this
 * width by `.nico-shop__aside--wide-only` in the narrow block below, so the summary is on screen
 * exactly once at every width.
 *
 * ONLY THE CHECKOUT EMITS EITHER CLASS. The basket and the review share this file and keep their
 * aside at every width - the review's holds the terms box and the submit button.
 */
.nico-shop__compact-total {
  margin-bottom: 1rem;
  border: 1px solid var(--nico-border);
  border-left: 3px solid var(--nico-band-accent);
  border-radius: var(--nico-radius);
  background-color: var(--nico-accent-soft);
}

.nico-shop__compact-total > summary {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 0.85rem 1rem;
  cursor: pointer;
}

.nico-shop__compact-label {
  flex: 1;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--nico-ink);
}

.nico-shop__compact-amount {
  font-size: 1.15rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.nico-shop__compact-body {
  padding: 0 1rem 1rem;
}

.nico-shop__compact-body .nico-summary {
  margin: 0;
  max-width: none;
}

/* On the wide layout the aside is beside the form and permanently in view, so the card is noise.
   Hidden here rather than rendered conditionally, because which of the two is visible is a
   question about the VIEWPORT and PHP cannot see one. */
@media (min-width: 62em) {
  .nico-shop__compact-total {
    display: none;
  }
}

/* ---------------------------------------------------------------- the checkout's choice cards */

/*
 * THE COUNTER, THE DELIVERY ADDRESS AND THE CONTACT NUMBER, each a <details> that shows what is
 * chosen on one line and opens into a list of radios. The disclosure is the browser's own - no
 * script - and the radios post `pickup_warehouse_id`, `shipping_address_id` and `contact_phone_id`.
 *
 * COPIED FROM account.css, NOT LOADED FROM IT. That file's `<details>` rules (the members "+" and
 * the billing filters) are about 1500 lines away from the three this card needs, and the checkout
 * sets `$pageStyles = ['shop']`. The two rules for the closed summary are restated here under this
 * page's own class names.
 *
 * A `.nico-pick` is NOT a `.nico-field`: `.nico-field input` makes every input a padded full-width
 * block, which would stretch the radios, and `.nico-field label` would restyle the row labels. The
 * title above the card is the `.nico-field__label` span, which stands alone.
 */
.nico-pick {
  margin-bottom: 1.25rem;
}

.nico-pick:last-child {
  margin-bottom: 0;
}

.nico-pick__card {
  border: 1px solid var(--nico-border);
  border-radius: var(--nico-radius);
  background-color: var(--nico-white);
}

/* `summary` is a `list-item` by default and draws its own triangle; it is a flex row here, and the
   engine-specific marker is switched off for the engines that still draw it. */
.nico-pick__card > summary,
.nico-shop__compact-total > summary {
  list-style: none;
}

.nico-pick__card > summary::-webkit-details-marker,
.nico-shop__compact-total > summary::-webkit-details-marker {
  display: none;
}

.nico-pick__card > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  min-height: 2.75rem;
  padding: 0.6rem 0.85rem;
  cursor: pointer;
}

/* The caret that says the row opens. Drawn from borders so it needs no glyph, no icon file and no
   colour of its own - it follows the text it sits beside. Turned over while the card is open. */
.nico-pick__card > summary::after,
.nico-shop__compact-total > summary::after {
  content: '';
  flex: none;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 2px solid var(--nico-ink-muted);
  border-bottom: 2px solid var(--nico-ink-muted);
  transform: translateY(-0.12rem) rotate(45deg);
}

.nico-pick__card[open] > summary::after,
.nico-shop__compact-total[open] > summary::after {
  transform: translateY(0.12rem) rotate(-135deg);
}

.nico-pick__card > summary:focus-visible,
.nico-shop__compact-total > summary:focus-visible {
  outline: 2px solid var(--nico-band-accent);
  outline-offset: 2px;
}

.nico-pick__current {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  font-weight: 600;
  color: var(--nico-ink);
}

.nico-pick__list {
  padding: 0.25rem 0.85rem;
  border-top: 1px solid var(--nico-border);
}

/* A row is the site's `.nico-choice` (radio, then a label that takes the width) with the label
   allowed to hold two lines, and the star and pencil riding at its end. */
.nico-pick__row {
  margin: 0;
  padding: 0.6rem 0;
}

.nico-pick__row + .nico-pick__row {
  border-top: 1px solid var(--nico-border);
}

.nico-pick__row label {
  flex: 1;
  min-width: 0;
}

/* A counter that cannot be chosen reads as unavailable, not as a row that failed to load. */
.nico-pick__row input:disabled + label {
  color: var(--nico-ink-muted);
  cursor: not-allowed;
}

.nico-pick__main,
.nico-pick__sub {
  display: block;
  overflow-wrap: anywhere;
}

.nico-pick__sub {
  margin-top: 0.1rem;
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--nico-ink-muted);
}

/* ---------------------------------------------------------------- narrow screens */

@media (max-width: 61.99em) {
  /* The panel stops being a sidebar and becomes the last block on the page, so its border earns
     less and its padding costs more. */
  .nico-shop-panel {
    padding: 1.15rem;
  }

  /* The checkout's aside, which prints its summary a second time below the buttons at this width
     once the collapsible card above them carries it. Only the checkout puts this class on its
     aside: the review's holds the terms box and the submit button, and the basket's is its only
     summary. */
  .nico-shop__aside--wide-only {
    display: none;
  }

  /* The step strip loses its connecting rules before it loses its steps: three discs and three
     words fit on a 390px line, three discs, three words and two 1.35rem rules do not. */
  .nico-steps-bar {
    gap: 0.4rem 0.9rem;
  }

  .nico-steps-bar__step + .nico-steps-bar__step::before {
    display: none;
  }
}

@media (max-width: 34.99em) {
  /* At phone width the words go and the numbered discs stay. The step's name is still in the
     markup and still read out - `.nico-visually-hidden` is not used here because the text is not
     hidden from the accessibility tree, only from the strip. */
  .nico-steps-bar__name {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
  }

  /* With the name clipped, a completed step's link is only as wide as its disc - measured at 20px,
     which is under the 24px minimum a finger can reliably hit. The padding buys the target back
     without moving the disc: it is transparent, so the strip looks identical and only the tappable
     area grows. `margin` cancels the space it would otherwise add between the three steps. */
  .nico-steps-bar__step a {
    padding: 0.35rem;
    margin: -0.35rem;
  }

  .nico-cart__thumb {
    width: 3.25rem;
    height: 3.25rem;
  }
}
