/* The customer's view, and the shop's new-order cue. */

/*
 * A board in the room, hung at the bottom of the page. The plaque itself — the
 * wood, the padding and the edge — comes from room.css.
 *
 * It is a sibling of .page__body rather than a child, so left alone it runs the
 * full width of the viewport while every card above it stops at the content
 * column. These two lines put it back in line with them: .page__body is
 * --content-max wide with --space-4 of inline padding and border-box sizing, so
 * the cards inside it span that minus twice the padding, and so does this.
 */
.storefront-footer {
  width: calc(100% - var(--space-4) * 2);
  max-width: calc(var(--content-max) - var(--space-4) * 2);
  margin-inline: auto;
  text-align: center;
  color: var(--color-text-muted);
}

.storefront-footer p { margin: 0 0 var(--space-1); }

/* A choice a customer makes once, so it is a target rather than a radio dot. */
.choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  min-height: var(--tap-target-lg);
  padding: var(--space-3);
  margin-block-end: var(--space-2);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
}

.choice:has(input:checked) {
  border-color: var(--color-action);
  background: var(--color-support);
}

.choice input { width: 1.5rem; height: 1.5rem; margin-block-start: 2px; }
.choice span { display: flex; flex-direction: column; }

/*
 * Agreement §3.8: where the order has got to. A step that has not happened is
 * shown as still to come rather than hidden — a customer wants to know what is
 * left, not just what is done.
 */
.timeline { list-style: none; margin: 0; padding: 0; }

.timeline__step {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) 0 var(--space-2) var(--space-5);
  position: relative;
  border-inline-start: 2px solid var(--color-border);
  margin-inline-start: var(--space-2);
}

.timeline__step::before {
  content: "";
  position: absolute;
  inset-inline-start: -7px;
  top: 1rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--color-canvas);
  border: 2px solid var(--color-border-strong);
}

.timeline__step--done { font-weight: 600; }
.timeline__step--done::before { background: var(--color-notice); border-color: var(--color-notice); }
.timeline__step--todo { color: var(--color-text-muted); }

.timeline__when { font-size: var(--text-sm); white-space: nowrap; }

/* ── The front page ─────────────────────────────────────────────────────── */

/*
 * The layout of the hero — the cut-out basket and the board beside it — lives in
 * room.css, because it only exists inside the room and it is written against the
 * plaque. What is left here is the type.
 */
.landing-hero__words h1 {
  margin: 0 0 var(--space-2);
  font-size: var(--text-2xl);
  text-wrap: balance;
}

.landing-hero__lead {
  max-width: 44ch;
  margin: 0 auto var(--space-4);
  font-size: var(--text-lg);
  text-wrap: pretty;
}

/* Three counters, side by side where there is room and stacked where there is
   not — the same rule as everywhere else on a phone. */
.landing-counters {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  margin-block-end: var(--space-4);
}

.landing-counters .card { margin: 0; }

/*
 * The plaques under the hours: what this phone could still do. Side by side
 * where the column is wide enough, stacked on a phone. With both hidden —
 * the phone has everything already — the row takes no room at all.
 */
.device-plaques {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

/* A board's gap below it, like every other board — but only while there is a
   plaque to show, or an empty row would double the hours board's own. */
.device-plaques:has(> :not([hidden])) { margin-block-end: var(--space-4); }

/*
 * A plaque is a board you press, so it is a <button> with a button's defaults
 * undone: the board's lettering and alignment, not the system's. Inside a room
 * the plaque rule supplies the wood, exactly as it does for a counter.
 */
.device-plaque {
  flex: 1 1 12rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
  margin: 0;
  font: inherit;
  color: inherit;
  text-align: start;
  cursor: pointer;
}

/* A span, because a button may not hold a heading — so it takes the weight an
   h2 has from base.css by hand, or it reads fainter than the hours above it. */
.device-plaque .card__title { margin: 0; font-weight: 650; }

/*
 * A counter board IS a link, so it needs an anchor's defaults undone: no
 * underline across the whole board, and the board's own colour rather than the
 * link colour. Inside a room the plaque rule outranks this and supplies
 * --color-on-plaque; this is what holds if the board is ever seen without one.
 */
.counter {
  display: block;
  color: var(--color-text);
  text-decoration: none;
}

/* The invitation at the foot of the board. It is no longer a link of its own —
   the board is — but it still has to LOOK like the way in, or a whole clickable
   card has no affordance at all. */
.counter__more {
  margin-block-end: 0;
  color: var(--color-link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* O6 — laid out only when there is something in it. */
.storefront-footer__social {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-block-start: var(--space-3);
}

/* ── A product, and its measures ──────────────────────────────────────────── */

/*
 * The tile is the product; the measures come when they are asked for. Every
 * measure of every product used to sit open at once, which on a counter of
 * thirty things is a wall of numbers to read past before finding the one you
 * came for.
 *
 * The tile needs to be a positioning context because the opener covers it.
 */
.good {
  position: relative;
}

/*
 * With a photograph the tile is words on the left and the picture on the right;
 * without one the words simply have the tile, which is why this is a modifier
 * and not the default. A product with no photograph is the normal case for a
 * long time and it has to look deliberate, not like a frame waiting to be
 * filled.
 */
.good--shown {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--space-3);
}

.good__photo {
  width: 3rem;
  height: 3rem;
  object-fit: cover;
  border-radius: var(--radius-sm);
  box-shadow: inset 0 1px 0 var(--tab-bevel), -1px 2px 4px rgb(0 0 0 / 45%);
}

/* The sheet's own, a little larger, beside the name it belongs to. */
.sheet__photo {
  width: 3.5rem;
  height: 3.5rem;
  object-fit: cover;
  border-radius: var(--radius-sm);
  box-shadow: inset 0 1px 0 var(--tab-bevel), -1px 2px 4px rgb(0 0 0 / 45%);
}

/* The tiny one: the till, and a cart line. Set into the row rather than raised
   off it, because neither is something to press. */
.good__pip {
  width: 1.75rem;
  height: 1.75rem;
  object-fit: cover;
  border-radius: var(--radius-sm);
  vertical-align: -0.4em;
  margin-inline-end: var(--space-2);
}

/*
 * The whole tile is the target, not a word on it — the same decision as the
 * counter boards on the front page, and for the same reason: on a phone a link
 * inside a tile is a thumb-width target inside something ten times its size.
 *
 * Hidden in the markup and revealed by the controller, so a browser without
 * scripts never shows a button that cannot do anything.
 */
.good__opener {
  position: absolute;
  inset: 0;
  width: 100%;
  padding: 0;
  border: 0;
  border-radius: inherit;
  background: none;
  cursor: pointer;
}

/* ── The sheet ────────────────────────────────────────────────────────────── */

.sheet__category { margin: 0; font-size: var(--text-sm); }

/* A package's sheet: what it saves, the Add button, then the parts at what each
   costs on its own. No colour of its own anywhere — the saving is carried by
   size and weight in the board's lettering, which room.css has already
   measured, rather than a green drawn for paper that vanishes on wood. */
.sheet__saving { margin: 0 0 var(--space-3); font-size: var(--text-lg); font-weight: 700; }
.sheet__parts { margin-block: var(--space-3); }
.sheet__figures { margin: 0; }

/* ── Checkout, in steps ──────────────────────────────────────────────────── */

/*
 * Four short steps on one board instead of one long form (checkout_controller.js).
 * Nothing in here hides anything: the controller sets `hidden`, so a browser with
 * no scripts gets every step stacked — the whole form, as it always was.
 */
.checkout__basket {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
}

/*
 * How far along: a channel cut across the board with herb green growing along
 * it, dot to dot, toward the kiondo at the end. The green is the coriander in
 * the hero (tokens.css --color-herb). --progress runs from 0 to 1 and the
 * controller sets it; --steps is how many stops share the width.
 */
.checkout-progress {
  --steps: 4;
  --dot: 1.75rem;
  --herb: var(--color-herb);
  --progress: 0;
  position: relative;
  display: grid;
  grid-template-columns: repeat(var(--steps), 1fr);
  margin: 0 0 var(--space-5);
  padding: 0;
  list-style: none;
}

/* The channel, then the green in it — both from the first stop's centre to the
   last one's. */
.checkout-progress::before,
.checkout-progress::after {
  content: "";
  position: absolute;
  inset-block-start: calc(var(--dot) / 2 - 2px);
  inset-inline-start: calc(50% / var(--steps));
  height: 4px;
  border-radius: 2px;
}

/* Cut across the grain like the rules between lines (room.css): the channel's
   floor in shadow, a lit lip along its lower wall. */
.checkout-progress::before {
  width: calc(100% - 100% / var(--steps));
  background: var(--relief-shadow);
  box-shadow: 0 1px 0 var(--relief-light);
}

.checkout-progress::after {
  width: calc((100% - 100% / var(--steps)) * var(--progress));
  background: var(--herb);
}

.checkout-progress__step {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  font-size: var(--text-sm);
  text-align: center;
}

/*
 * A hole drilled into the board: the same wood, sunk, its upper-right wall in
 * shadow and a lit lip lower-left — the room's one bulb, as everywhere. It is
 * the wood and not a colour so the channel does not show through it.
 */
.checkout-progress__dot {
  position: relative;
  display: grid;
  place-items: center;
  width: var(--dot);
  height: var(--dot);
  border-radius: 50%;
  background:
    linear-gradient(var(--plaque-veil), var(--plaque-veil)),
    var(--plaque-image) center / cover no-repeat;
  box-shadow:
    inset -2px 2px 3px var(--relief-shadow),
    inset 1px -1px 0 var(--relief-light);
}

/* Where they are: a ring of green round the hole. */
.checkout-progress__step[aria-current="step"] .checkout-progress__dot {
  box-shadow:
    0 0 0 3px var(--herb),
    inset -2px 2px 3px var(--relief-shadow),
    inset 1px -1px 0 var(--relief-light);
}

.checkout-progress__step[aria-current="step"] .checkout-progress__label { font-weight: 700; }

/* Done: the hole filled with green, and a leaf come up out of it. */
.checkout-progress__step.is-done .checkout-progress__dot {
  background: var(--herb);
  box-shadow: inset 1px -1px 0 var(--relief-light);
}

.checkout-progress__step.is-done .checkout-progress__dot::after {
  content: "";
  position: absolute;
  inset-block-start: -0.45rem;
  inset-inline-end: -0.4rem;
  width: 0.85rem;
  height: 0.5rem;
  border-radius: 0 100% 0 100%;
  background: var(--herb);
  rotate: -25deg;
}

/* The last stop is the kiondo itself, dim until the green reaches it. */
.checkout-progress__step--basket .checkout-progress__dot {
  background: none;
}

.checkout-progress__step--basket .mark {
  width: 100%;
  height: 100%;
  filter: grayscale(1) brightness(0.8);
}

.checkout-progress__step--basket[aria-current="step"] .mark { filter: none; }

.checkout-step + .checkout-step { margin-block-start: var(--space-5); }
.checkout-step__title { margin-block-end: var(--space-1); }
.checkout-step__title:focus:not(:focus-visible) { outline: none; }
.checkout-step__kicker { margin-block-end: var(--space-4); }

.checkout-step__nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
  margin-block-start: var(--space-4);
}

/* The way on takes the room; Back stays a quiet word at the left. */
.checkout-step__onward { flex: 1 1 12rem; }

/* The last look: each answer on its own row, with a way back to change it. */
.checkout-review { margin: 0 0 var(--space-4); }

.checkout-review__row {
  display: grid;
  grid-template-columns: 4.5rem 1fr auto;
  align-items: baseline;
  gap: var(--space-2) var(--space-3);
  padding-block: var(--space-2);
}

/* The same groove as the rules between lines on the bill, between rows only. */
.checkout-review__row + .checkout-review__row {
  border-block-start: 1px solid var(--relief-shadow);
  box-shadow: inset 0 1px 0 var(--relief-light);
}

.checkout-review dt { font-size: var(--text-sm); }
.checkout-review dd { margin: 0; overflow-wrap: anywhere; }

/* ── It is in the basket ─────────────────────────────────────────────────── */

/*
 * The order page's welcome, once (orders/_celebration). The grains fall BEHIND
 * the kiondo, which is stacked above them, so they are gone into it the moment
 * they pass the rim — no mask, no clipping, just the basket in front.
 */
.celebration { text-align: center; }

.celebration__basket {
  position: relative;
  width: 10rem;
  margin: 0 auto var(--space-3);
}

.celebration__basket .mark {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: auto;
}

.celebration__title {
  margin: 0 0 var(--space-2);
  font-size: var(--text-2xl);
  font-weight: 650;
}

/* Standing still, the grains have nowhere to be. */
.celebration__grain { display: none; }

.celebration__grain--maize { width: 0.55rem; height: 0.7rem; border-radius: 45% 45% 50% 50%; background: var(--brand-accent); }
.celebration__grain--bean  { width: 0.8rem; height: 0.5rem; border-radius: 50%; background: var(--brand-primary); }
.celebration__grain--gram  { width: 0.45rem; height: 0.45rem; border-radius: 50%; background: var(--color-herb-deep); }
.celebration__grain--leaf  { width: 0.9rem; height: 0.5rem; border-radius: 0 100% 0 100%; background: var(--color-herb); }

/*
 * All the motion on this page, and only for someone who has not asked for less
 * (the room's rule, room.css). Asked for less, the line simply is where it is,
 * the leaf is simply there, and the basket stands still with its words.
 */
@media (prefers-reduced-motion: no-preference) {
  .checkout-progress::after { transition: width 450ms ease-out; }

  .checkout-progress__step.is-done .checkout-progress__dot::after {
    animation: a-leaf-comes-up 380ms ease-out 250ms both;
  }

  .celebration__grain {
    display: block;
    position: absolute;
    inset-block-start: 22%;
    inset-inline-start: var(--x);
    animation: into-the-basket 850ms cubic-bezier(0.55, 0, 0.9, 0.55) both;
    animation-delay: calc(250ms + var(--i) * 110ms);
  }

  .celebration__basket .mark {
    animation: the-basket-nods 520ms ease-in-out 1.6s both;
  }
}

@keyframes a-leaf-comes-up {
  from { scale: 0; }
  to   { scale: 1; }
}

@keyframes into-the-basket {
  from { translate: 0 -9rem; rotate: 0deg; opacity: 0; }
  20%  { opacity: 1; }
  to   { translate: 0 1.75rem; rotate: 220deg; opacity: 1; }
}

@keyframes the-basket-nods {
  0%, 100% { rotate: 0deg; }
  35%      { rotate: -4deg; }
  70%      { rotate: 3deg; }
}

/*
 * Where the boards turn to paper (room.css does it for the same two asks), the
 * leaf drawn for wood is too pale, and the drilled holes have no wood to show.
 */
@media (prefers-contrast: more), (prefers-reduced-transparency: reduce) {
  .checkout-progress { --herb: var(--color-herb-deep); }
  .checkout-progress__dot { background: var(--color-surface-sunken); }
}
