/* Radio group ----------------------------------------------------------
   The <fieldset> around a list of radio cards. It exists to name the group
   for a screen reader (its legend is sr-only), so it draws nothing itself. */

.radio-group {
  margin: 0;
  padding: 0;
  border: 0;
  min-inline-size: 0;
}

/* Locker code: the typed way to a locker, under the map's opener. */

.pickup-code {
  margin-top: var(--space-4);
}

/* Radio card -----------------------------------------------------------
   Delivery / payment / pickup point choice. The input stays in the DOM
   (sr-only) so forms and htmx keep working; :has() drives the styling. */

.radio-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  cursor: pointer;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast), background-color var(--dur-fast);
}

.radio-card:hover {
  border-color: var(--line-strong);
}

.radio-card:has(input:checked) {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
  background: var(--surface-raised);
}

.radio-card:has(input:focus-visible) {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.radio-card:has(input:disabled) {
  opacity: 0.5;
  cursor: not-allowed;
}

.radio-card__mark {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  border: 2px solid var(--control-border);
  display: grid;
  place-items: center;
}

.radio-card:has(input:checked) .radio-card__mark {
  border-color: var(--primary);
}

.radio-card:has(input:checked) .radio-card__mark::after {
  content: "";
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: var(--primary);
}

.radio-card__body {
  flex: 1;
  min-width: 0;
}

.radio-card__title {
  display: block;
  font-weight: 700;
}

.radio-card__desc {
  display: block;
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.radio-card__logo {
  flex: none;
  height: 1.75rem;
  width: auto;
  border-radius: var(--radius-sm);
}

.radio-card__price {
  flex: none;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.radio-list {
  display: grid;
  gap: var(--space-3);
}

/* Radio list, side by side — the checkout's "how do you want to buy?" choice.
   The track count follows the number of cards rather than being fixed at
   three: a shop that lets customers log in but takes no new sign-ups draws two,
   and a fixed three-column track left the last third of the row empty. A phone
   gets them back in one column. */
.radio-list--row {
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
}

@media (max-width: 639px) {
  .radio-list--row {
    grid-auto-flow: row;
    grid-auto-columns: auto;
  }
}

/* A saved address is three lines, so its description keeps its own breaks. */
.radio-card__desc--lines { white-space: pre-line; }

/* Auth panel ------------------------------------------------------------
   Login or registration fields inside the checkout form, set apart from the
   delivery fields they otherwise look exactly like. */

.auth-panel {
  display: grid;
  gap: var(--space-4);
  padding: var(--space-5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
}

.auth-panel__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
}

.auth-panel__aside {
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

/* Identity bar ----------------------------------------------------------
   Who is logged in, and the way out. The --secondary edge makes it read as
   state; a message would be an .alert. */

.identity-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  padding: var(--space-3) var(--space-4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--secondary);
  border-radius: var(--radius-md);
}

.identity-bar__who {
  font-weight: 700;
}

.identity-bar__mail {
  color: var(--ink-muted);
  font-size: var(--text-sm);
}

/* Discount code ---------------------------------------------------------
   The block under the payment step: a title, then the code input with its
   button beside it (stacked on a phone), or — once a code is on — the code
   and what it takes off, with the way to remove it on the right. The refusal
   is the block's own line, so it is shown here rather than by .field--error,
   and it paints the input the way .field--error would. */

.discount-code {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius-md);
}

.discount-code__title {
  font-size: var(--text-base);
  font-weight: 700;
}

.discount-code__form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--space-2) var(--space-3);
}

/* A code that died on the cart gets its remove button on a row of its own,
   under the input, so the apply button keeps its place beside it. */
.discount-code__form > .btn--ghost {
  grid-column: 1 / -1;
  justify-self: start;
}

.discount-code__error {
  display: block;
  grid-column: 1 / -1;
}

.discount-code__form:has(.discount-code__error) .field__control {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px var(--danger-soft);
}

.discount-code__applied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-weight: 700;
}

@media (max-width: 639px) {
  .discount-code__form {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Stepper (checkout steps) -------------------------------------------- */

.stepper__step {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}

.stepper__num {
  flex: none;
  width: 2rem;
  height: 2rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-family: var(--font-brand);
  font-weight: 700;
  background: var(--primary-fill);
  color: var(--on-primary);
}

.stepper__title {
  font-size: var(--text-xl);
}

.stepper__step.is-done .stepper__num {
  background: var(--success-soft);
  color: var(--success);
}

.stepper__step.is-pending {
  opacity: 0.5;
}

.stepper__step.is-pending .stepper__num {
  background: var(--surface-raised);
  color: var(--ink-muted);
}

/* Cart line ----------------------------------------------------------- */

.cart-line {
  display: grid;
  grid-template-columns: 6rem 1fr;
  gap: var(--space-4);
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--line);
}

.cart-line__media {
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--surface);
}

.cart-line__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cart-line__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.cart-line__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.cart-line__name {
  font-weight: 700;
}

.cart-line__name:hover {
  color: var(--primary);
}

.cart-line__meta {
  font-size: var(--text-sm);
  color: var(--ink-muted);
}

.cart-line__remove {
  flex: none;
  background: none;
  border: 0;
  color: var(--ink-muted);
  padding: var(--space-1);
  border-radius: 50%;
}

.cart-line__remove:hover {
  color: var(--danger);
  background: var(--danger-soft);
}

.cart-line__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: auto;
}

@media (min-width: 640px) {
  .cart-line {
    grid-template-columns: 9rem 1fr;
  }
}

/* Summary (cart and checkout) ----------------------------------------- */

/* The card is a <section>; its figures are two <dl>s inside it, the
   lines and the totals. The margin is the one the card had when it was a
   <dl> itself, kept so the page does not move. */
.summary {
  margin-block: 1em;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.summary__rows {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.summary--sticky {
  position: sticky;
  top: calc(4rem + var(--space-6));
}

.summary__title {
  font-size: var(--text-xl);
  margin-bottom: var(--space-2);
}

.summary__row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  font-size: var(--text-sm);
  color: var(--ink-soft);
}

.summary__row dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

.summary__row--placeholder dd {
  color: var(--ink-muted);
  font-style: italic;
}

.summary__row--total {
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--ink);
}

.summary__row--total dd {
  color: var(--primary);
}

.summary .btn {
  margin-top: var(--space-3);
}

/* Meter: the cart's "41 zl to go" bar under the summary title. */

.meter {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.meter__text {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--ink-soft);
}

.meter--done .meter__text {
  color: var(--success);
  font-weight: 700;
}

.meter__track {
  height: 0.375rem;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
}

.meter__bar {
  height: 100%;
  width: 0;
  background: var(--primary);
  border-radius: inherit;
  transition: width 0.4s ease;
}

.meter--done .meter__bar {
  background: var(--success);
}

.summary__lines {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--line);
}

/* Two-column shop layout (items + summary) --------------------------- */

.shop-layout {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: 1fr;
  align-items: start;
}

@media (min-width: 1024px) {
  .shop-layout {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  }
}

/* Order confirmation -------------------------------------------------- */

.order-confirmation {
  max-width: 36rem;
  margin-inline: auto;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  padding-block: var(--space-12);
}

.order-confirmation__icon {
  width: 4.5rem;
  height: 4.5rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--success-soft);
  color: var(--success);
  box-shadow: 0 0 0 8px color-mix(in srgb, var(--success) 8%, transparent);
}

.order-confirmation__number {
  font-family: var(--font-brand);
  font-size: var(--text-4xl);
  letter-spacing: 0.06em;
}

/* The status as one line under the number — a label and a pill — where a
   card with a single row stood. */
.order-confirmation__status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--ink-muted);
  font-size: var(--text-sm);
}

.order-confirmation .summary {
  width: 100%;
  text-align: left;
  margin-top: var(--space-4);
}

/* The e-mail form a stranger with the order's link gets. The page centres its
   column; a form reads left-aligned and as wide as the column. */
.order-confirmation__form {
  width: 100%;
  text-align: left;
}

/* =====================================================================
   Locker picker — the checkout's InPost geowidget, in a native <dialog>
   wearing the shared .dialog shell (components.css). What is left for CSS
   here is the room the map needs.
   ===================================================================== */
.pickup-dialog {
  width: min(920px, 96vw);
  height: min(680px, 90vh);
  overflow: hidden;
}

/* The widget is a custom element, so it is inline until told otherwise —
   and an inline box gives the map no height at all. The head is measured
   here rather than assumed: --pickup-dialog-head is the one number the
   two rules share. */
.pickup-dialog {
  --pickup-dialog-head: 4rem;
}

.pickup-dialog inpost-geowidget {
  display: block;
  width: 100%;
  height: calc(100% - var(--pickup-dialog-head));
}

/* The stand-in DEV_MODE puts where the map would be. InPost's map answers
   only on the domain its token names, so a local shop lists a few made-up
   lockers instead; picking one fills the same fields the map does. */
.pickup-dialog__standin {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  height: calc(100% - var(--pickup-dialog-head));
  padding: var(--space-4);
  overflow: auto;
}

.pickup-dialog__points {
  display: grid;
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Forced colours (Windows high contrast): the chosen card's pink edge and
   halo, the radio's dot and the meter's fill are all colours the system
   palette throws away, so they are redrawn in its own. */
@media (forced-colors: active) {
  .radio-card:has(input:checked) {
    border: 2px solid Highlight;
  }

  .radio-card:has(input:checked) .radio-card__mark {
    border-color: Highlight;
  }

  .radio-card:has(input:checked) .radio-card__mark::after {
    forced-color-adjust: none;
    background: Highlight;
  }

  .meter__track {
    border: 1px solid CanvasText;
  }

  .meter__bar {
    forced-color-adjust: none;
    background: Highlight;
  }
}
