@layer components {

/* ── Order entry points ──
   The order form is a modal (see the overrides layer below). These are the
   buttons that open it: one in each nav, one at the end of What We Offer. */

/* Desktop nav: a small filled pill, so "Place Order" reads as an action
   rather than one more section to scroll to. Sits last in the row, after
   Merch. Text then basket icon, 5px apart (Figma: Assets → node 218:2260);
   font size and padding follow the site, not the mockup. Weight is Medium
   (500), per the mockup and matching the nav links. */
.nav__order {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  align-self: center;
  padding: 0.55rem 1.2rem;
  border: none;
  border-radius: 999px;
  background: var(--brand-primary);
  color: #fff;
  font: inherit;
  font-size: 1.1rem;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s ease;
}

.nav__order:hover {
  background: var(--brand-primary-dark);
}

/* The basket keeps its native 18×16 (set by the width/height attributes). */
.nav__order-icon {
  display: block;
  flex: none;
}

/* Mobile menu: a full-size .btn, left-aligned with the links above it, and
   pill-shaped to match the desktop button, with the same text + basket. */
.nav__panel-order {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  align-self: flex-start;
  margin-top: 0.5rem;
  border-radius: 999px;
}

/* End of What We Offer: after browsing every group, the next step. Just the
   button, centered — its label says everything. */
.offer__order-cta {
  display: flex;
  justify-content: center;
  margin-top: 3.5rem;
}

/* ── The form (inside the modal) ── */
/* Callout: the one thing to know before ordering, set apart so it isn't
   skimmed past. Same panel as the What We Offer intro (cream fill, light
   green outline, 12px radius), with the footer's envelope icon since the
   message is about email. Full text color, not muted grey — Patricia wants
   it easy to read. */
.order-form__lead {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  margin: 1.25rem 0 1.75rem;
  padding: 0.9rem 1.1rem;
  border: 1px solid var(--brand-primary-light);
  border-radius: 12px;
  background: var(--color-bg-alt);
  line-height: 1.5;
  color: var(--color-text);
  font-weight: 500;
}

/* Sized and nudged to sit on the first line of text (1.5 line-height at
   16px = 24px line; a 20px icon + 2px drop centers it). */
.order-form__lead-icon {
  flex: none;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  color: var(--brand-primary);
}

/* Sections ("Your order" / "Your details") are set apart by their headings
   and spacing alone. Within "Your order", categories get a green label and
   light-green rule (below) so they read differently from the faint grey
   hairlines between item rows. */
.order-form__section {
  margin: 0 0 2rem;
  padding: 0;
  border: none;
}

/* Legends are notoriously hard to lay out; float: left is the reliable way
   to make one behave like an ordinary block heading across browsers. */
.order-form__legend {
  float: left;
  width: 100%;
  margin: 0 0 1rem;
  padding: 0;
  color: var(--brand-primary);
  font-family: var(--font-heading);
  font-size: 1.25rem;
  font-weight: 500;
}

.order-form__legend + * {
  clear: both;
}

/* Item list */
.order-form__group {
  margin-bottom: 1.75rem;
}

/* Smaller cousin of .offer-group__label: category name with a rule to the
   right, so the list echoes the card groups on the page — and, like them,
   in green, so a category reads differently from the grey item rows. */
.order-form__group-label {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 0.25rem;
  color: var(--brand-primary);
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.order-form__group-label::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--brand-primary-light);
}

.order-form__items {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* One row per product size: name | price | stepper. The stepper column is
   the same width as the size columns below, so steppers line up down the
   whole list. */
.order-item {
  display: grid;
  grid-template-columns: 1fr auto 8.25rem;
  align-items: center;
  column-gap: 1rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--color-border);
}

.order-item > .qty-stepper {
  justify-self: center;
}

/* Groups whose products all share sizes and prices (the granolas): the
   sizes are named once in a header row, and each product gets one row with
   a stepper per size. --size-cols is set on the group in index.njk. */
.order-grid__head,
.order-item--sizes {
  grid-template-columns: 1fr repeat(var(--size-cols, 2), 8.25rem);
}

.order-grid__head {
  display: grid;
  align-items: end;
  column-gap: 1rem;
  padding: 0.4rem 0 0.2rem;
}

.order-grid__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: var(--color-text-muted);
  font-size: 0.8rem;
  line-height: 1.2;
}

.order-item__cell {
  display: flex;
  justify-content: center;
}

/* Only shown on phones, where the header row is hidden (responsive layer). */
.order-item__cell-label {
  display: none;
}

/* ── Quantity stepper: − [qty] + ──
   A pill holding two buttons and the real number box. Once a quantity is
   picked the outline turns into a 2px green stroke: the 1px border plus a
   1px ring drawn by ::after. The ring sits ABOVE the buttons, so a button's
   hover fill can't paint over it, and the 2px never shifts the layout. */
.qty-stepper {
  position: relative;
  display: inline-grid;
  grid-template-columns: 2.25rem 2.5rem 2.25rem;
  align-items: center;
  border: 1px solid #c9c9c9;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-bg);
  transition: border-color 0.15s ease;
}

.qty-stepper::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px transparent;
  pointer-events: none;
  transition: box-shadow 0.15s ease;
}

.qty-stepper.is-picked {
  border-color: var(--brand-primary);
}

.qty-stepper.is-picked::after {
  box-shadow: inset 0 0 0 1px var(--brand-primary);
}

/* Keyboard focus is on the box inside; ring the whole pill. */
.qty-stepper:has(.qty-stepper__input:focus-visible) {
  outline: 2px solid var(--brand-primary);
  outline-offset: 2px;
}

.qty-stepper__btn {
  height: 2.25rem;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--brand-primary);
  font: inherit;
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  /* No double-tap zoom when tapping + quickly on phones. */
  touch-action: manipulation;
}

/* Hover only where there's a real pointer: on phones a tapped button would
   otherwise keep its hover fill until you tap somewhere else. */
@media (hover: hover) {
  .qty-stepper__btn:hover:not(:disabled) {
    background: var(--color-bg-alt);
  }
}

.qty-stepper__btn:disabled {
  color: #c9c9c9;
  cursor: default;
}

/* The number box, minus its border and the browser's own spin arrows.
   1rem text: below that, iOS Safari zooms the page when it's tapped. */
.qty-stepper__input {
  width: 100%;
  min-width: 0;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--color-text);
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
  appearance: textfield;
  -moz-appearance: textfield;
}

.qty-stepper__input::-webkit-outer-spin-button,
.qty-stepper__input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.qty-stepper__input::placeholder {
  color: var(--color-text-muted);
  font-weight: 400;
  opacity: 1;
}

.qty-stepper__input:focus {
  outline: none;
}

.qty-stepper.is-picked .qty-stepper__input {
  color: var(--brand-primary-dark);
}

.order-item:last-child {
  border-bottom: none;
}

.order-item__name {
  font-weight: 500;
}

.order-item__size {
  display: block;
  color: var(--color-text-muted);
  font-size: 0.8rem;
  font-weight: 400;
}

.order-item__price {
  color: var(--brand-primary-dark);
  font-family: var(--font-heading);
  font-size: 1.1rem;
  font-weight: 600;
}

/* Details fields */
.order-form__fields {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.25rem;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.field--wide {
  grid-column: 1 / -1;
}

.field__label {
  font-size: 0.9rem;
  font-weight: 600;
}

.field__optional {
  color: var(--color-text-muted);
  font-weight: 400;
}

/* 1rem (16px) text on inputs is deliberate: below that, iOS Safari zooms
   the whole page in when a field is tapped. */
.field__input {
  width: 100%;
  padding: 0.7rem 0.8rem;
  border: 1px solid #c9c9c9;
  border-radius: 6px;
  background: var(--color-bg);
  color: var(--color-text);
  font: inherit;
  font-size: 1rem;
}

textarea.field__input {
  resize: vertical;
}

/* ── "Ready by" date field ──
   Desktop browsers draw an empty date field as "mm/dd/yyyy" with a calendar
   icon. iOS Safari draws it as a blank box, shorter than the other inputs
   and wider than its column, so nobody can tell it's a field. */
.field__date {
  position: relative;
  display: block;
}

.field__date-hint {
  display: none;
}

/* Same height as the text inputs (1.5 line-height + padding + border), so an
   empty date field doesn't collapse. min-width: 0 alone did NOT fix iOS's
   overflow on a real iPhone; the appearance: none rule below does. */
input[type="date"].field__input {
  display: block;
  min-width: 0;
  min-height: calc(1.5em + 1.4rem + 2px);
}

/* iOS only: -webkit-touch-callout exists solely in iOS browsers (Safari and
   Chrome on iPhone/iPad both use WebKit there), so desktop browsers keep
   their own "mm/dd/yyyy" display untouched. */
@supports (-webkit-touch-callout: none) {
  /* The real fix for the width: iOS draws date fields with its own native
     control, which has a built-in minimum width and ignores our width rule,
     so it ran past the right edge of the other fields. Turning off the native
     appearance makes it size like an ordinary input. Tapping it still opens
     Apple's date picker. */
  input[type="date"].field__input {
    -webkit-appearance: none;
    appearance: none;
  }

  /* iOS centers the chosen date; line it up with the other fields. The
     min-height keeps the empty field from collapsing to a thin strip. */
  input[type="date"].field__input::-webkit-date-and-time-value {
    min-height: 1.5em;
    text-align: left;
  }

  /* The hint sits over the empty field like a placeholder. pointer-events:
     none lets the tap fall through to the field, which opens iOS's picker. */
  .field__input.is-empty + .field__date-hint {
    display: block;
    position: absolute;
    top: 50%;
    left: 0.8rem;
    transform: translateY(-50%);
    color: var(--color-text-muted);
    pointer-events: none;
  }
}

.field__input:focus {
  outline: 2px solid var(--brand-primary);
  outline-offset: 1px;
  border-color: var(--brand-primary);
}

/* Bot check + error line */
.order-form__turnstile:not(:empty) {
  margin-bottom: 1rem;
}

.order-form__status {
  margin: 0 0 1rem;
  color: #a33a1f;
  font-weight: 600;
}

.order-form__status:empty {
  margin: 0;
}

/* Footer: running total + send. Sits below the scrolling body (see the
   modal layout in the overrides layer), so it's always visible without
   needing to be sticky. Breaks out of the modal's side padding like
   .flyer-modal__bar does at the top, so its rule spans edge to edge. */
.order-form__footer {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: 0 -1.5rem;
  padding: 0.9rem 1.5rem;
  padding-bottom: calc(0.9rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--color-border);
  background: var(--color-bg);
}

.order-form__total {
  display: flex;
  flex-direction: column;
  margin: 0;
}

.order-form__total-label {
  font-size: 0.85rem;
  font-weight: 600;
}

.order-form__note {
  color: var(--color-text-muted);
  font-weight: 400;
}

.order-form__total output {
  color: var(--brand-primary-dark);
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.2;
}

/* One line, always: on phones the footer is narrow, and the button was
   breaking into "Place / order" while the total's note took the space. */
.order-form__submit {
  flex: none;
  white-space: nowrap;
}

.order-form__submit:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* Replaces the form once the order is sent. */
/* Equal top and bottom: with the header bar hidden, this is the modal's
   only content, so it should sit centered in the white panel. */
.order-thanks {
  padding: 2.5rem 0;
  text-align: center;
}

.order-thanks:focus {
  outline: none;
}

.order-thanks h3 {
  margin: 0 0 0.5rem;
  color: var(--brand-primary);
  font-size: 1.35rem;
  font-weight: 500;
}

.order-thanks p {
  margin: 0 0 1.5rem;
  color: var(--color-text-muted);
}

}

/* The modal shell itself. In the overrides layer, same as the flyer modal
   (09-flyer-modal.css) it's built on, so these win over the flyer's sizing
   by coming later in the same layer. */
@layer overrides {

/* ── Only the middle scrolls ──
   The flyer shell this is built on scrolls the whole dialog. Chrome draws
   that scrollbar as a square strip along the dialog's edge, which cuts
   across the rounded corners. Instead the dialog is a fixed-height frame:
     header bar (fixed) / form body (scrolls) / footer (fixed)
   so the scrollbar only runs between the header and footer rules and never
   reaches a corner. Same pattern as Bootstrap's "scrollable" modal.
   Each level passes the height limit down: flex column + min-height: 0 is
   what lets a flex child shrink below its content height and scroll. */
.order-modal {
  overflow: hidden;
}

.order-modal[open] {
  display: flex;
  flex-direction: column;
}

/* No bottom padding: the footer should sit flush on the modal's bottom
   edge, not float 1.5rem above it. */
.order-modal .flyer-modal__inner {
  flex: 1 1 auto;
  min-height: 0;
  padding-bottom: 0;
}

.order-modal .flyer-modal__bar {
  flex: none;
}

.order-form {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* display: flex above would otherwise beat the `hidden` attribute, which
   is how the form gets swapped for the thank-you message. */
.order-form[hidden] {
  display: none;
}

/* The scrolling part. Negative side margins (re-padded inside) put the
   scrollbar at the modal's right edge instead of 1.5rem in. overscroll-
   behavior stops a scroll that hits the end from moving the page behind. */
.order-form__body {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0 -1.5rem;
  padding: 0 1.5rem;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Same slim scrollbar as the other modals (see 07-nutrition-modal.css). */
  scrollbar-width: thin;
  scrollbar-color: #c9c9c9 transparent;
}

/* Thank-you screen: no header bar. Its own Close button does the job, and
   the bar's title and X would just repeat it. Escape and clicking outside
   still close the modal. */
.order-modal.is-sent .flyer-modal__bar {
  display: none;
}

/* Wider than the portrait flyer (560px): the item rows need the room. */
@media (min-width: 701px) {
  .order-modal {
    max-width: min(680px, 92vw);
  }
}

}

@layer responsive {

@media (max-width: 700px) {
  .order-form__fields {
    grid-template-columns: 1fr;
  }

  /* One-size rows: name with its price underneath, stepper on the right. */
  .order-item {
    grid-template-columns: 1fr auto;
    column-gap: 0.75rem;
    row-gap: 0.1rem;
  }

  .order-item > .order-item__name {
    grid-column: 1;
  }

  .order-item > .order-item__price {
    grid-column: 1;
    grid-row: 2;
    font-size: 1rem;
  }

  .order-item > .qty-stepper {
    grid-column: 2;
    grid-row: 1 / span 2;
  }

  /* Shared-size groups: no header row. The name gets its own line, and each
     size becomes a small box with its own size and price, side by side. */
  .order-grid__head {
    display: none;
  }

  .order-item--sizes {
    grid-template-columns: repeat(var(--size-cols, 2), minmax(0, 1fr));
    row-gap: 0.5rem;
    column-gap: 0.6rem;
    padding: 0.75rem 0;
  }

  .order-item--sizes > .order-item__name {
    grid-column: 1 / -1;
  }

  .order-item__cell {
    flex-direction: column;
    align-items: stretch;
    gap: 0.4rem;
    padding: 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: 10px;
  }

  .order-item__cell-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    color: var(--color-text-muted);
    font-size: 0.8rem;
  }

  .order-item__cell-label .order-item__price {
    font-size: 0.95rem;
  }

  .order-item__cell .qty-stepper {
    grid-template-columns: 1fr 2.5rem 1fr;
  }

  /* Bigger tap targets on phones. */
  .qty-stepper__btn {
    height: 2.5rem;
  }

  .order-form__submit {
    padding: 0.9rem 1.1rem;
  }
}

}
