/*
 * LOMOND REWARDS — the visual language.
 *
 * EDITORIAL, NOT GAMIFIED. Every decision here is the restrained one: the
 * balance is set in the display serif because it is the most important number
 * on the page, the panels are ivory and taupe rather than coloured tiles, and
 * the single accent is one hairline of antique gold. There is no badge, no
 * tier, no progress bar and no medal. A furniture retailer's loyalty programme
 * should read like a statement from a shop, not a level-up screen.
 *
 * NOTHING HERE IS A NEW COLOUR. Every value is a `--lf-*` token from
 * `style.css`, sampled from the supplied logo. Adding a "rewards colour" would
 * be inventing a brand asset nobody approved.
 *
 * EVERY SELECTOR IS SCOPED to `.lf-rw*`, `.lf-news` or `.lf-signup__*`. This
 * file cannot restyle a product page, a category or a checkout, so it cannot
 * cause a regression outside the feature it belongs to.
 */

/* ============================================================ product page */

/*
 * The one line in the catalogue. It sits beside the buy button and states a
 * POINTS figure and nothing else — see `inc/rewards-ui.php` for why no cash
 * equivalent appears anywhere near a product.
 *
 * The mark is a 5px gold dot, not an icon: at this size an icon becomes a
 * smudge and a second thing to read, and the sentence carries itself.
 */
/* ================================================ the earn panel, on the PDP
   A premium incentive, not a promotion. One soft cream surface with a warm gold
   hairline, sitting under the basket button where the decision is made:

     the figure   the largest thing in the panel, in the Lomond serif, because
                  the number IS the argument
     the rule     what a point is worth, stated as the general rule it is
     the link     a footnote, never a second call to action

   The panel is cream against the ivory information panel above it, so the two
   read as different KINDS of thing — one tells you about the product, this one
   tells you what buying it earns.                                            */

/*
 * WHY IT NO LONGER READS AS A BUTTON.
 *
 * It sat directly beneath a solid navy full-width control, and it had the same
 * silhouette: an enclosing border, a 10px radius and a filled ground, at the
 * same width. Two stacked rectangles of equal width where the first is a
 * button — the eye reads the second as one too, and hesitates over it.
 *
 * Four changes, none of which cost it any presence:
 *   NO ENCLOSING BORDER   a border is what makes a shape a control. The
 *                         surface alone now says "this is a surface" — a
 *                         panel, not something to press.
 *   4px, NOT 10px         a tight radius reads as a printed panel; a generous
 *                         one reads as a control.
 *   MORE AIR ABOVE        1.6rem instead of 1.1rem, so the two are separate
 *                         things rather than a stack.
 *   MORE PADDING INSIDE   a button's padding hugs its label; a panel's does
 *                         not. Generous padding is most of what distinguishes
 *                         the two at a glance.
 *
 * And the figure grows rather than shrinks — the panel gets quieter as an
 * object while the number it exists to show gets louder.
 */
/*
 * SLIMMED TO A STRIP. The panel was ~130px of stacked rows directly beneath the
 * basket button, which put a secondary benefit at the same visual weight as the
 * primary action. It is now ONE row — mark, sentence, link — at about half the
 * height, still on its own warm surface so it reads as a benefit rather than as
 * another line of body copy, but clearly subordinate to the button above it.
 *
 * The figure keeps its size. Shrinking the strip is not a reason to shrink the
 * number: the number is the reason the strip exists.
 */
/*
 * A PURCHASE INCENTIVE, NOT FOOTER METADATA.
 *
 * This was a thin cream strip carrying a 19px outline icon and .95rem grey
 * copy, and against the approved design it read as a caption that happened to
 * contain a number. Three changes, none of them structural: a warmer ground
 * with a gold hairline so it is a surface rather than a tint; a filled gold
 * star at 24px so the reward is legible as a reward before it is read; and the
 * earn sentence at full navy contrast rather than at body-copy grey.
 *
 * Still deliberately NOT button-like — no heavy border, no shadow. It sits
 * directly under the CTA and must never compete with it.
 */
.lf-rwbuy {
  display: flex; align-items: center; flex-wrap: wrap;
  column-gap: clamp(.85rem, 1.6vw, 1.1rem); row-gap: .3rem;
  margin: clamp(1rem, 1.8vw, 1.25rem) 0 0;
  min-height: 66px;
  padding: clamp(.8rem, 1.5vw, 1rem) clamp(1.05rem, 2vw, 1.3rem);
  background: #FBF6EC;
  border: 0;
  box-shadow: inset 0 0 0 1px var(--lf-gold-line);
  border-radius: 4px;
}
.lf-rwbuy__icon { flex: none; color: var(--lf-gold); line-height: 0; }
.lf-rwbuy__icon svg { width: 24px; height: 24px; display: block; }

/* The earn sentence. Sans for the words, serif for the number — the same
   treatment the rewards card in the footer gives its figures, so a customer
   meets one visual idea of "this is a points figure" across the site. */
.lf-rwbuy__earn {
  flex: 1 1 auto; margin: 0;
  font-family: var(--lf-sans); font-size: 1rem;
  line-height: 1.25; color: var(--lf-navy); letter-spacing: .01em;
}
.lf-rwbuy__value {
  font-family: var(--lf-serif); font-weight: 500;
  font-size: clamp(1.4rem, 1.9vw, 1.65rem); line-height: 1;
  color: var(--lf-navy); letter-spacing: -.012em;
  margin: 0 .14rem;
}
/* A footnote, held to the 44px target because it is a standalone action — the
   same rule the footer panel's explainer link follows. */
/* The way out of the panel has to look like a way out — it was .82rem grey
   with a 34%-opacity underline, which is a footnote, not an action. */
.lf-rwbuy__link {
  flex: none;
  display: inline-flex; align-items: center; gap: .4rem; min-height: 44px;
  font-size: .875rem; font-weight: 500; color: var(--lf-navy);
  /* The underline now lives on the label span (see below), so the element-level
     gradient is cleared or it would draw a second rule under the arrow. */
  background-image: none;
  background-repeat: no-repeat;
  background-position: 0 calc(50% + .72em);
  background-size: 100% 1px;
  transition: background-size .35s var(--lf-ease), background-image .3s var(--lf-ease),
              color .3s var(--lf-ease);
}
.lf-rwbuy__link .lf-rw-link__label {
  background-image: linear-gradient(rgba(141, 106, 58, .7), rgba(141, 106, 58, .7));
  background-repeat: no-repeat;
  background-position: 0 calc(100% - .05em);
  background-size: 100% 1px;
  transition: background-image .3s var(--lf-ease), background-size .35s var(--lf-ease);
}
.lf-rwbuy__link .lf-rw-link__arrow {
  flex: none; width: 16px; height: 16px; display: block;
  transition: transform .3s var(--lf-ease);
}
@media (hover: hover) and (pointer: fine) {
  .lf-rwbuy__link:hover { color: var(--lf-navy); }
  .lf-rwbuy__link:hover .lf-rw-link__label {
    background-image: linear-gradient(var(--lf-navy), var(--lf-navy));
  }
  .lf-rwbuy__link:hover .lf-rw-link__arrow { transform: translateX(3px); }
}
@media (prefers-reduced-motion: reduce) {
  .lf-rwbuy__link .lf-rw-link__label,
  .lf-rwbuy__link .lf-rw-link__arrow { transition: none; }
}
.lf-rwbuy__link:focus-visible { outline: 2px solid var(--lf-navy); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .lf-rwbuy__link { transition: none; } }

@media (max-width: 560px) {
  /* The icon keeps its column — dropping it above the text would push the
     figure down a line for no gain on the width where vertical room is
     scarcest. */
  .lf-rwbuy { padding: .85rem 1rem; }
  .lf-rwbuy__value { font-size: 1.45rem; }
  /* `flex: 1 1 100%` here put the earn line on its own row and left the mark
     stranded alone above it — three rows for a strip whose whole purpose is to
     be one. `auto` keeps the mark and the sentence together and lets only the
     link drop, which is the row that can afford to. */
  .lf-rwbuy__earn { flex: 1 1 auto; }
  .lf-rwbuy__link { min-height: 40px; }
}

.lf-rw-earn {
  display: flex; align-items: baseline; flex-wrap: wrap;
  column-gap: .85rem; row-gap: .2rem;
  margin: .9rem 0 0; padding: 0;
  font-family: var(--lf-sans); font-size: .84rem; line-height: 1.5;
  color: var(--lf-taupe-deep); letter-spacing: .01em;
}
.lf-rw-earn__mark {
  flex: 0 0 auto; width: 5px; height: 5px; border-radius: 50%;
  background: var(--lf-gold-sheet); transform: translateY(-2px);
}
.lf-rw-earn strong { font-weight: 500; color: var(--lf-navy); }
.lf-rw-earn__text { flex: 0 1 auto; }
/*
 * The supporting link sits on the same line where there is room and wraps
 * beneath where there is not — it is a footnote to the earning statement, not a
 * second call to action, so it is never allowed to become a button.
 */
.lf-rw-earn__link {
  flex: 0 0 auto; font-size: .78rem; color: var(--lf-taupe);
  border-bottom: 1px solid var(--lf-taupe-pale); padding-bottom: 1px;
  transition: color .25s var(--lf-ease), border-color .25s var(--lf-ease);
}
.lf-rw-link {
  font-size: .82rem; color: var(--lf-taupe-deep);
  border-bottom: 1px solid var(--lf-taupe-pale); padding-bottom: 1px;
  transition: color .25s var(--lf-ease), border-color .25s var(--lf-ease);
}

/* ================================================================= basket */

.lf-rw-basket {
  margin: 0 0 1.25rem; padding: 1.1rem 1.15rem;
  background: var(--lf-taupe-wash); border: 1px solid var(--lf-line);
  font-family: var(--lf-sans); font-size: .86rem; color: var(--lf-taupe-deep);
}
/*
 * A quiet section label rather than a heading. The basket's own hierarchy runs
 * from the items to the total to the checkout button, and a heading here would
 * insert a fourth level into a screen whose whole job is to get out of the way.
 */
.lf-rw-basket__eyebrow {
  margin: 0 0 .6rem; font-size: .68rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--lf-taupe);
}
.lf-rw-basket__earn { margin: 0; }
.lf-rw-basket__cap { margin: .5rem 0 0; font-size: .78rem; color: var(--lf-taupe-mid); }
.lf-rw-basket__applied-line { margin: 0; }
.lf-rw-basket__earn strong { font-weight: 500; color: var(--lf-navy); }
.lf-rw-basket__prompt,
.lf-rw-basket__have { margin: .7rem 0 0; font-size: .82rem; line-height: 1.55; }
.lf-rw-basket__prompt a { color: var(--lf-navy); border-bottom: 1px solid var(--lf-taupe-pale); }

.lf-rw-basket__row { display: flex; gap: .5rem; margin-top: .6rem; }
.lf-rw-basket__row input {
  flex: 1 1 7rem; min-width: 0; min-height: 44px; padding: 0 .75rem;
  font-family: var(--lf-sans); font-size: .95rem; color: var(--lf-charcoal);
  background: #fff; border: 1px solid var(--lf-line-strong);
}
.lf-rw-basket__apply,
.lf-rw-basket__remove {
  flex: 0 0 auto; min-height: 44px; padding: 0 1.15rem; cursor: pointer;
  font-family: var(--lf-sans); font-size: .72rem; font-weight: 400;
  letter-spacing: .14em; text-transform: uppercase;
  border: 1px solid var(--lf-navy); background: var(--lf-navy); color: #fff;
  transition: background .3s var(--lf-ease), color .3s var(--lf-ease);
}
/*
 * REMOVE IS DE-EMPHASISED BY TONE, NOT BY SIZE.
 *
 * It was 38px tall, which read correctly as the quieter of the two actions and
 * was measured at 38px by the render QA pass — under the 44px minimum touch
 * target at 430 and 390. A secondary action is still an action somebody has to
 * hit with a thumb, so the height goes back to 44 and the de-emphasis is
 * carried entirely by the ghost fill and the pale border.
 */
.lf-rw-basket__remove {
  background: transparent; color: var(--lf-navy); border-color: var(--lf-taupe-pale);
  padding: 0 .9rem; min-height: 44px; letter-spacing: .1em;
}

.lf-rw-basket__applied {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-top: .7rem;
  padding-top: .7rem; border-top: 1px solid var(--lf-line);
}
.lf-rw-basket__applied p { margin: 0; }
.lf-rw-basket__applied strong { font-weight: 500; color: var(--lf-navy); }

.lf-rw-basket__status { margin: .55rem 0 0; font-size: .8rem; min-height: 1.2em; }
.lf-rw-basket__status.is-error { color: #8A2F2F; }
.lf-rw-basket__status.is-ok { color: var(--lf-navy); }

/* checkout summary row — WooCommerce's own table, so only the cell is styled */
.lf-rw-checkout__line { display: block; font-size: .8rem; line-height: 1.5; color: var(--lf-taupe-deep); }
.lf-rw-checkout__line--earn { color: var(--lf-navy); }
.lf-rw-checkout__line--spend { color: var(--lf-taupe-deep); }

/* =========================================================== confirmation */

.lf-rw-thanks {
  margin: 1.75rem 0; padding: 1.4rem 1.5rem;
  background: var(--lf-cream); border: 1px solid var(--lf-gold-line);
}
.lf-rw-thanks__points {
  margin: 0; font-family: var(--lf-serif); font-size: clamp(1.25rem, 2.4vw, 1.6rem);
  line-height: 1.3; color: var(--lf-navy);
}
.lf-rw-thanks__points strong { font-weight: 500; }
.lf-rw-thanks__eyebrow {
  margin: 0 0 .5rem; font-size: .68rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--lf-taupe);
}
.lf-rw-thanks__note {
  margin: .55rem 0 0; font-family: var(--lf-sans); font-size: .88rem;
  line-height: 1.6; color: var(--lf-taupe-deep); max-width: 54ch;
}
.lf-rw-thanks__actions { margin: 1.1rem 0 0; }
.lf-rw-thanks__small {
  margin: .8rem 0 0; font-family: var(--lf-sans); font-size: .8rem;
  line-height: 1.55; color: var(--lf-taupe-mid);
}
.lf-rw-thanks__small strong { color: var(--lf-taupe-deep); font-weight: 400; }

/* ============================================================= my account */

.lf-rw { font-family: var(--lf-sans); color: var(--lf-taupe-deep); }

.lf-rw__flash {
  margin: 0 0 1.25rem; padding: .8rem 1rem; font-size: .86rem;
  border-left: 2px solid var(--lf-navy); background: var(--lf-taupe-wash);
}
.lf-rw__flash--ok { border-left-color: var(--lf-gold-sheet); }
.lf-rw__flash--warn { border-left-color: #8A2F2F; color: #8A2F2F; }

/*
 * THE HERO. Ivory ground, one gold hairline along the top edge, and the balance
 * in the display serif at a size nothing else on the page competes with. The
 * gold is punctuation — remove it and the panel still says everything.
 */
.lf-rw__hero {
  padding: clamp(1.5rem, 4vw, 2.25rem);
  background: var(--lf-ivory);
  border: 1px solid var(--lf-line);
  border-top: 2px solid var(--lf-gold-sheet);
}
.lf-rw__eyebrow { margin: 0 0 .5rem; }
.lf-rw__title {
  display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap;
  margin: 0; font-family: var(--lf-serif); font-weight: 400; color: var(--lf-navy);
  line-height: 1;
}
.lf-rw__points { font-size: clamp(2.6rem, 8vw, 4rem); letter-spacing: -.01em; }
.lf-rw__unit {
  font-family: var(--lf-sans); font-size: .78rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--lf-taupe);
}
/* The cash value, immediately under the balance and never hidden behind an
   interaction — the customer must never do the division themselves. */
.lf-rw__worth {
  margin: .4rem 0 0; font-family: var(--lf-serif); font-size: clamp(1.1rem, 3vw, 1.35rem);
  color: var(--lf-taupe-deep);
}
.lf-rw__toward,
/*
 * THE RESTORE NOTE sits where the cash value would be, and is set in the same
 * quiet sans as the rest of the supporting copy — NOT in red. A deficit is a
 * consequence of a refund the customer asked for, not an error or a warning,
 * and colouring it like one would make an ordinary situation feel like a
 * problem with their account.
 */
.lf-rw__restore {
  margin: .5rem 0 0; max-width: 54ch;
  font-family: var(--lf-sans); font-size: .88rem; line-height: 1.6;
  color: var(--lf-taupe-deep);
}
.lf-rw__deficit { margin: .9rem 0 0; font-size: .86rem; line-height: 1.6; max-width: 52ch; color: var(--lf-taupe-deep); }

.lf-btn--quiet {
  background: transparent; color: var(--lf-navy); border-color: var(--lf-navy);
  min-height: 44px; padding: 0 1.4rem; font-size: .74rem;
}

/*
 * AVAILABLE AND PENDING, side by side inside the hero and never summed.
 *
 * Two items, not four: lifetime totals moved to a single line at the foot of
 * the page. They are the least actionable numbers here — nothing a customer
 * does changes what they already earned — and giving them equal billing with
 * the spendable balance is how a dashboard stops having a subject.
 */
.lf-rw__split {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0; margin: 1.6rem 0 0; padding: 1.1rem 0 0;
  border-top: 1px solid var(--lf-line);
}
.lf-rw__split-item { margin: 0; padding-right: 1.5rem; }
.lf-rw__split-item + .lf-rw__split-item {
  padding-right: 0; padding-left: 1.5rem; border-left: 1px solid var(--lf-line);
}
.lf-rw__split dt {
  margin: 0 0 .3rem; font-size: .68rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--lf-taupe);
}
.lf-rw__split dd {
  margin: 0; font-family: var(--lf-serif); font-size: 1.65rem;
  line-height: 1.1; color: var(--lf-navy);
}
.lf-rw__split dd span {
  display: block; margin-top: .25rem; font-family: var(--lf-sans);
  font-size: .74rem; letter-spacing: .03em; color: var(--lf-taupe-mid);
}
.lf-rw__split-item.is-quiet dd { color: var(--lf-taupe-mid); }

.lf-rw__actions {
  display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
  margin: 1.5rem 0 0;
}
/*
 * ONE action carries weight and the other is a link. The hero already has a
 * dominant element — the balance — so a solid navy button here would give the
 * panel two centres. A rule that thickens on interaction is enough.
 */
.lf-rw__cta {
  display: inline-flex; align-items: center; gap: .7rem; min-height: 44px;
  font-family: var(--lf-sans); font-size: .76rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--lf-navy);
  border-bottom: 1px solid var(--lf-navy); padding-bottom: 2px;
  transition: gap .3s var(--lf-ease);
}

/* the guest-claim invitation */
.lf-rw__claim {
  margin-top: 1.25rem; padding: 1.2rem 1.3rem;
  background: var(--lf-cream); border: 1px solid var(--lf-gold-line);
}
.lf-rw__claim-title {
  margin: 0 0 .4rem; font-family: var(--lf-serif); font-weight: 400;
  font-size: clamp(1.15rem, 2.6vw, 1.4rem); color: var(--lf-navy);
}
.lf-rw__claim p { margin: 0 0 .9rem; font-size: .86rem; line-height: 1.6; }
.lf-rw__claim-form { margin: 0; }

/* ------------------------------------------------------------ the history */

.lf-rw__section-title {
  margin: 2.25rem 0 .9rem; font-family: var(--lf-sans); font-size: .72rem;
  letter-spacing: .18em; text-transform: uppercase; font-weight: 400; color: var(--lf-navy);
}
.lf-rw__tablewrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.lf-rw__table { width: 100%; border-collapse: collapse; font-size: .86rem; }
.lf-rw__table th {
  text-align: left; font-family: var(--lf-sans); font-weight: 400;
  font-size: .66rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--lf-taupe); padding: 0 1rem .55rem 0; border-bottom: 1px solid var(--lf-line-strong);
}
.lf-rw__table td {
  padding: .95rem 1rem .95rem 0; border-bottom: 1px solid var(--lf-line);
  vertical-align: baseline;
}
/*
 * THE MOVEMENT IS THE HEADLINE OF ITS ROW, and the order or reason sits under
 * it a step quieter. That single typographic decision is most of what separates
 * this from the admin ledger it is derived from: an admin reads a table of
 * equal-weight columns, a customer reads a list of things that happened.
 */
.lf-rw__label { display: block; color: var(--lf-navy); }
.lf-rw__detail {
  display: block; margin-top: .15rem; font-size: .8rem; color: var(--lf-taupe-mid);
  max-width: 44ch;
}
.lf-rw__when { color: var(--lf-taupe); white-space: nowrap; font-size: .82rem; }
.lf-rw__num {
  text-align: right; padding-right: 0 !important;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.lf-rw__table td.lf-rw__num {
  font-family: var(--lf-serif); font-size: 1.15rem; color: var(--lf-navy);
}
.lf-rw__table tr.is-spent td.lf-rw__num,
.lf-rw__table tr.is-spent .lf-rw__label { color: var(--lf-taupe-mid); }

/*
 * The state badge appears on perhaps one row in ten, so it is set INLINE under
 * the label rather than given a column of its own — a column that is empty nine
 * times out of ten is a column of whitespace pretending to be information.
 * It says its state in words: colour is never the only carrier of meaning.
 */
.lf-rw__pill {
  display: inline-block; margin-top: .35rem; padding: .12rem .5rem;
  font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
  border: 1px solid var(--lf-line-strong); color: var(--lf-taupe); white-space: nowrap;
}
.lf-rw__pill--pending { border-color: var(--lf-gold-line); color: var(--lf-taupe-deep); }
.lf-rw__pill--unclaimed { border-color: var(--lf-gold-sheet); color: var(--lf-taupe-deep); }

.lf-rw__empty { font-size: .88rem; color: var(--lf-taupe); max-width: 56ch; }

/* the two explanatory panels */
.lf-rw__panels { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; margin-top: 2rem; }
.lf-rw__panel { padding: 1.2rem 1.3rem; background: var(--lf-stone); border: 1px solid var(--lf-line); }
.lf-rw__panel-title {
  margin: 0 0 .55rem; font-family: var(--lf-sans); font-size: .72rem;
  letter-spacing: .18em; text-transform: uppercase; font-weight: 400; color: var(--lf-navy);
}
.lf-rw__panel p { margin: 0 0 .6rem; font-size: .85rem; line-height: 1.65; }
.lf-rw__panel p:last-child { margin-bottom: 0; }
.lf-rw__panel-sub { color: var(--lf-taupe-mid); font-size: .8rem !important; }

.lf-rw__lifetime {
  margin: 1.75rem 0 0; padding-top: 1.25rem; border-top: 1px solid var(--lf-line);
  font-size: .82rem; color: var(--lf-taupe-mid);
}
.lf-rw__lifetime strong { color: var(--lf-taupe-deep); font-weight: 400; }

/* ================================================= newsletter — the form */

/*
 * SELF-CONTAINED, AND IT HAS TO BE.
 *
 * `style.css` used to carry `.lf-signup form { display: flex }` and
 * `.lf-signup input { min-height: 48px; border: … }` from the old
 * single-field signup, and both leaked onto this form the moment it sat in the
 * footer: the row, the consent label and the status message became flex
 * siblings, so the field and the button stacked, and the consent CHECKBOX
 * inherited a 48px height and a text input's border.
 *
 * Those two rules went with the band rebuild, so nothing is being overridden
 * any more — but the `.lf-signup`-scoped duplicates below stay, because this
 * component also renders in the account panel where no such scope exists, and
 * because a descendant rule reappearing in `style.css` must not be able to
 * reach inside the form again.
 */
.lf-news,
.lf-signup .lf-news { display: block; margin: .9rem 0 0; }
.lf-signup .lf-news__row { display: flex; }
.lf-signup .lf-news__consent input[type="checkbox"],
.lf-news__consent input[type="checkbox"] {
  flex: 0 0 auto; width: 18px; height: 18px; min-height: 0;
  padding: 0; border: 0; background: none; appearance: auto;
}
.lf-news__row { display: flex; gap: .75rem; flex-wrap: wrap; }
.lf-news__row input[type="email"] {
  flex: 1 1 16rem; min-width: 0; min-height: 48px; padding: 0 1rem;
  font-family: var(--lf-sans); font-size: .95rem; color: var(--lf-charcoal);
  background: #fff; border: 1px solid var(--lf-line-strong);
}
.lf-news__row button {
  flex: 0 0 auto; min-height: 48px; padding: 0 1.9rem; cursor: pointer;
  font-family: var(--lf-sans); font-size: .82rem; letter-spacing: .14em; text-transform: uppercase;
  border: 1px solid var(--lf-navy); background: var(--lf-navy); color: #fff;
  transition: background .3s var(--lf-ease);
}

/*
 * THE CONSENT ROW. Never pre-ticked, never visually de-emphasised into
 * something people tick without reading, and the label is the exact sentence
 * stored as the consent record. A 20px target with a real gap is a deliberate
 * accessibility floor, not a style.
 */
/*
 * THE LABEL IS THE TAP TARGET, so the label carries the 44px floor — not the
 * 18px box, which is correctly small. At 430px the two-line label measured
 * 40px, just under, which a screenshot cannot show and the render pass can.
 */
.lf-news__consent {
  display: flex; align-items: flex-start; gap: .6rem; margin: .8rem 0 0;
  min-height: 44px; padding-top: .1rem;
  font-size: .8rem; line-height: 1.55; color: var(--lf-taupe-deep); cursor: pointer;
  max-width: 52ch;
}
.lf-news__consent input { margin-top: .18rem; accent-color: var(--lf-navy); }
.lf-news__status { margin: .55rem 0 0; font-size: .8rem; min-height: 1.2em; }
.lf-news__status.is-error { color: #8A2F2F; }
.lf-news__status.is-ok { color: var(--lf-navy); }
.lf-news--compact .lf-news__row input[type="email"] { flex-basis: 12rem; }


/* ======================================================== the rewards page */

/*
 * THE PUBLIC EXPLAINER. Full-bleed alternating grounds — ivory, white, cream —
 * with one navy hero, so the page reads as an editorial sequence rather than a
 * stack of cards. There is no accent fill anywhere: the antique gold appears
 * twice, both times as a hairline, and the composition carries the rest.
 */
.lf-rwp { display: block; }

.lf-rwp__hero {
  background: var(--lf-navy); color: var(--lf-white);
  padding-block: clamp(3.5rem, 9vw, 7rem);
  border-bottom: 2px solid var(--lf-gold-on-navy);
}
/*
 * The hero copy is a measure column that starts at the PAGE GUTTER, not one
 * centred inside it. Applying `.lf-wrap`'s `margin-inline: auto` and a 46rem
 * max-width to the same element centred the whole block, so the display heading
 * began 250px to the right of every section beneath it — visible immediately in
 * the render pass and invisible in the markup.
 */
.lf-rwp__hero-inner { max-width: 46rem; }
.lf-rwp__hero .lf-eyebrow { color: var(--lf-gold-on-navy); }
.lf-rwp__title {
  margin: .6rem 0 0; font-family: var(--lf-serif); font-weight: 400;
  font-size: clamp(2.2rem, 6vw, 3.9rem); line-height: 1.08;
  letter-spacing: -.005em; color: var(--lf-white);
}
.lf-rwp__lede {
  margin: 1.4rem 0 0; max-width: 40ch;
  font-family: var(--lf-sans); font-size: clamp(1rem, 1.6vw, 1.12rem);
  line-height: 1.6; color: rgba(255, 255, 255, .78);
}
.lf-rwp__cta { display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; margin: 2.2rem 0 0; }
/* Reversed out of the navy: the shared `.lf-btn` is navy-on-navy here. */
.lf-rwp__hero .lf-btn {
  background: var(--lf-white); border-color: var(--lf-white); color: var(--lf-navy);
}
/* The honest line where a join button would otherwise be. Reversed out of the
   navy hero, quieter than the lede, and it never pretends to be a control. */
.lf-rwp__pending {
  margin: 1.4rem 0 0; max-width: 46ch;
  font-family: var(--lf-sans); font-size: .86rem; line-height: 1.65;
  color: rgba(255, 255, 255, .62);
}
.lf-rwp__signin {
  min-height: 44px; display: inline-flex; align-items: center;
  font-family: var(--lf-sans); font-size: .78rem; letter-spacing: .16em;
  text-transform: uppercase; color: var(--lf-white);
  border-bottom: 1px solid rgba(255, 255, 255, .38); padding-bottom: 2px;
}

/* earn / save / use */
.lf-rwp__three { background: var(--lf-white); padding-block: clamp(3rem, 7vw, 5.5rem); }
.lf-rwp__steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
  background: var(--lf-line); border: 1px solid var(--lf-line);
}
.lf-rwp__step { background: var(--lf-white); padding: clamp(1.5rem, 3vw, 2.25rem); }
.lf-rwp__step-kicker {
  margin: 0 0 .9rem; font-family: var(--lf-sans); font-size: .68rem;
  letter-spacing: .22em; text-transform: uppercase; color: var(--lf-gold);
}
.lf-rwp__step-fact {
  margin: 0; font-family: var(--lf-serif); font-weight: 400;
  font-size: clamp(1.35rem, 2.8vw, 1.8rem); line-height: 1.25; color: var(--lf-navy);
}
/* The equals sign is drawn, not typed at body weight — it is the hinge of the
   sentence and it should read as a mark. */
.lf-rwp__step-eq { display: inline-block; margin: 0 .45rem; color: var(--lf-taupe-mid); font-size: .8em; }
.lf-rwp__step-note {
  margin: .8rem 0 0; font-family: var(--lf-sans); font-size: .85rem;
  line-height: 1.65; color: var(--lf-taupe-deep); max-width: 34ch;
}

/* the worked example */
.lf-rwp__example { background: var(--lf-cream); padding-block: clamp(3rem, 7vw, 5.5rem); }
.lf-rwp__example-inner { text-align: center; }
.lf-rwp__example .lf-eyebrow { color: var(--lf-gold); }
/*
 * ONE COMPOSED STATEMENT, not a calculator. The arrow is the whole interaction:
 * a form with an input would turn a promise into a task, and the answer is the
 * same for everybody anyway.
 */
.lf-rwp__sum {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(1rem, 4vw, 2.5rem); flex-wrap: wrap;
  margin: 1.2rem 0 0; font-family: var(--lf-serif); color: var(--lf-navy);
  font-size: clamp(2.2rem, 7vw, 4rem); line-height: 1;
}
.lf-rwp__sum-arrow { color: var(--lf-gold-sheet); font-size: .6em; }
.lf-rwp__sum-to small {
  display: block; margin-top: .35rem; font-family: var(--lf-sans);
  /*
   * A FLOOR, because `.2em` of a fluid figure collapses. The figure clamps down
   * to ~35px at 390px wide, which made this label 7px — measured, not
   * estimated, and unreadable at any letter-spacing. `max()` keeps the
   * proportional relationship everywhere it works and stops it only where it
   * stops working. Pre-existing on the example band; found when the birthday
   * band inherited it.
   */
  font-size: max(11px, .2em); letter-spacing: .22em; text-transform: uppercase; color: var(--lf-taupe);
}
.lf-rwp__sum-note {
  margin: 1.6rem auto 0; max-width: 46ch; font-family: var(--lf-sans);
  font-size: .88rem; line-height: 1.7; color: var(--lf-taupe-deep);
}

/* more ways to earn */
.lf-rwp__more { background: var(--lf-white); padding-block: clamp(3rem, 7vw, 5.5rem); }
.lf-rwp__more-inner {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem); align-items: start;
}
.lf-rwp__h2 {
  margin: .5rem 0 0; font-family: var(--lf-serif); font-weight: 400;
  font-size: clamp(1.6rem, 3.4vw, 2.3rem); line-height: 1.2; color: var(--lf-navy);
}
.lf-rwp__more-bonus {
  display: flex; align-items: baseline; gap: .5rem; margin: 1.1rem 0 0;
  font-family: var(--lf-serif); color: var(--lf-navy);
}
.lf-rwp__more-bonus strong { font-weight: 400; font-size: clamp(2rem, 5vw, 2.9rem); line-height: 1; }
.lf-rwp__more-bonus span {
  font-family: var(--lf-sans); font-size: .72rem; letter-spacing: .2em;
  text-transform: uppercase; color: var(--lf-taupe);
}
.lf-rwp__more-note {
  margin: 1.1rem 0 0; font-family: var(--lf-sans); font-size: .88rem;
  line-height: 1.7; color: var(--lf-taupe-deep); max-width: 46ch;
}
.lf-rwp__more-form { padding-top: .4rem; }

/* the FAQ */
.lf-rwp__faq { background: var(--lf-stone); padding-block: clamp(3rem, 7vw, 5.5rem); }
.lf-rwp__faq-inner { max-width: 52rem; }
.lf-rwp__faqlist { margin: 1.75rem 0 0; }
/*
 * OPEN, not an accordion. Seven short answers a customer is deciding on is
 * exactly the case where a disclosure widget makes somebody click seven times
 * to read a page they could have skimmed — and it hides the answers from
 * anybody scanning for the one that worries them.
 */
.lf-rwp__faqitem { padding: 1.35rem 0; border-top: 1px solid var(--lf-line-strong); }
.lf-rwp__faqitem:last-child { border-bottom: 1px solid var(--lf-line-strong); }
.lf-rwp__faqlist dt {
  font-family: var(--lf-serif); font-size: 1.15rem; color: var(--lf-navy); line-height: 1.35;
}
.lf-rwp__faqlist dd {
  margin: .5rem 0 0; font-family: var(--lf-sans); font-size: .88rem;
  line-height: 1.7; color: var(--lf-taupe-deep); max-width: 62ch;
}
.lf-rwp__close { display: flex; align-items: center; gap: 2rem; flex-wrap: wrap; margin: 2.25rem 0 0; }
.lf-rwp__close .lf-rwp__signin { color: var(--lf-navy); border-bottom-color: var(--lf-taupe-pale); }

/* ====================================================== registration opt-in */

/*
 * THE ACCOUNT FORM'S OWN FIELDS.
 *
 * `style.css` styles form rows for `.woocommerce-checkout` only, so the login
 * and registration forms fell through to browser defaults: the render pass
 * measured a 21px input on a 430px viewport. That is a pre-existing gap rather
 * than something this feature introduced, but a Rewards opt-in block cannot sit
 * inside a form whose own fields look unfinished, and a 21px target fails the
 * accessibility floor regardless of who left it there.
 *
 * The values are copied from the checkout rule deliberately — one visual
 * language for every form on the site. The selector is WooCommerce's own class
 * on the FORM element rather than a body class: a body class is a fact about
 * the page, and scoping a component to one means the component only works where
 * somebody remembered to be.
 */
.woocommerce-form-login .form-row,
.woocommerce-form-register .form-row { margin: 0 0 1.1rem; display: block; }
.woocommerce-form-login .form-row label,
.woocommerce-form-register .form-row label {
  display: block; font-size: .8rem; letter-spacing: .04em;
  color: var(--lf-taupe-deep); margin-bottom: .35rem;
}
.woocommerce-form-login .form-row .required,
.woocommerce-form-register .form-row .required { color: var(--lf-navy); text-decoration: none; }
.woocommerce-form-login .input-text,
.woocommerce-form-register .input-text {
  width: 100%; min-height: 48px; padding: .7rem .8rem; font: inherit; font-size: .95rem;
  border: 1px solid var(--lf-line); background: #fff; border-radius: 0;
  transition: border-color .2s var(--lf-ease);
}
.woocommerce-form-login .input-text:focus-visible,
.woocommerce-form-register .input-text:focus-visible {
  outline: 2px solid var(--lf-navy); outline-offset: 1px; border-color: var(--lf-navy);
}

/*
 * THE SUBMIT BUTTON, WHICH WAS 21px TALL.
 *
 * `style.css` styles buttons for the checkout and for the theme's own `.lf-btn`,
 * and WooCommerce's `.woocommerce-Button` on the account forms fell through to
 * the browser default — measured at 65x21 on the live registration form. That
 * is the primary action of the whole account journey, below the touch-target
 * floor, and looking like a 1998 form control on a premium furniture shop.
 *
 * Given the same treatment as `.lf-btn`, scoped to the two account forms so
 * nothing else on the site changes.
 */
.woocommerce-form-login button[type="submit"],
.woocommerce-form-register button[type="submit"] {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 48px; padding: 0 1.9rem; cursor: pointer;
  font-family: var(--lf-sans); font-size: .82rem; font-weight: 400;
  letter-spacing: .14em; text-transform: uppercase;
  border: 1px solid var(--lf-navy); background: var(--lf-navy); color: #fff;
  border-radius: 0;
  transition: background .3s var(--lf-ease);
}
.woocommerce-form-login button[type="submit"]:focus-visible,
.woocommerce-form-register button[type="submit"]:focus-visible {
  outline: 2px solid var(--lf-navy); outline-offset: 3px;
}
/* The password-visibility toggle WooCommerce injects must not inherit any of
   that — it is an icon inside the field, not an action. */
.woocommerce-form-login .show-password-input,
.woocommerce-form-register .show-password-input { min-height: 0; padding: 0; }

@media (hover: hover) and (pointer: fine) {
  .woocommerce-form-login button[type="submit"]:hover,
  .woocommerce-form-register button[type="submit"]:hover { background: var(--lf-navy-80); }
}

.lf-reg__intro { margin: 0 0 1.4rem; }
.lf-reg__title {
  margin: 0; font-family: var(--lf-serif); font-weight: 400;
  font-size: clamp(1.3rem, 3vw, 1.7rem); color: var(--lf-navy);
}
.lf-reg__lede {
  margin: .45rem 0 0; font-family: var(--lf-sans); font-size: .88rem;
  line-height: 1.65; color: var(--lf-taupe-deep); max-width: 46ch;
}
/*
 * The optional block is visibly a DIFFERENT THING from the account fields —
 * its own ground, its own rule — because the one thing this form must never do
 * is let marketing consent look like part of creating an account.
 */
.lf-reg__optin {
  margin: 1.5rem 0 .5rem; padding: 1.1rem 1.15rem;
  background: var(--lf-stone); border: 1px solid var(--lf-line);
}
.lf-reg__optin-head {
  display: flex; align-items: baseline; gap: .9rem; flex-wrap: wrap; margin: 0 0 .7rem;
  font-family: var(--lf-sans); font-size: .66rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--lf-taupe);
}
.lf-reg__optin-bonus { color: var(--lf-gold); letter-spacing: .14em; }
.lf-reg__optin .lf-news__consent { margin: 0; }
.lf-reg__optin .lf-news__support { margin-top: .6rem; }

/* =============================================== newsletter — the framing */

.lf-news__support {
  margin: .6rem 0 0; font-size: .76rem; line-height: 1.6;
  color: var(--lf-taupe-mid); max-width: 52ch;
}
.lf-news__support a { color: var(--lf-taupe-deep); border-bottom: 1px solid var(--lf-taupe-pale); }

/* ======================================= the footer band's rewards panel
   The panel's BOX — margin, background, border, radius, shadow — is in
   `style.css`, because the band has to hold its shape on a page where this
   stylesheet is not enqueued. Everything inside it is here. */

/* THE PANEL'S OWN MASTHEAD. It rendered at 11.2px against 11.5px in the
   editorial eyebrow beside it and 15.2px of body copy — technically a heading,
   optically a caption. A little more size, a little more tracking and the full
   navy make it the first thing read inside the card, which is what it is. */
.lf-rwband__head {
  margin: 0 0 clamp(1rem, 1.45vw, 1.3rem);
  font-family: var(--lf-sans); font-size: .75rem; font-weight: 400;
  letter-spacing: .24em; text-transform: uppercase; color: var(--lf-navy);
}

/* ---- the two offers
   A GRID WITH A BORDER FOR THE DIVIDER, not a pseudo-element: the rule then
   spans exactly the taller of the two offers and needs no height guessing, and
   it disappears on its own the moment the columns stack. */
.lf-rwband__offers {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: clamp(1.1rem, 1.9vw, 1.6rem);
}
.lf-rwband__offer {
  position: relative;
  display: flex; align-items: flex-start; gap: clamp(.8rem, 1.15vw, .95rem);
}
/*
 * THE DIVIDER IS A FADED HAIRLINE, NOT A BORDER.
 *
 * A `border-left` runs the full height of the taller offer and butts hard
 * against the padding at both ends — mechanically correct and visually loud,
 * which is how it read. This is a 1px column inset from both ends and faded out
 * at top and bottom, so it separates the two offers without drawing a line
 * across the card. Warm gold at low alpha rather than grey, because grey is the
 * one colour nothing else in this band uses.
 */
.lf-rwband__offer + .lf-rwband__offer { padding-left: clamp(1.1rem, 1.9vw, 1.6rem); }
.lf-rwband__offer + .lf-rwband__offer::before {
  content: ""; position: absolute; left: 0; top: 6%; bottom: 6%; width: 1px;
  background: linear-gradient(to bottom,
    rgba(141, 106, 58, 0) 0%,
    rgba(141, 106, 58, .22) 22%,
    rgba(141, 106, 58, .22) 78%,
    rgba(141, 106, 58, 0) 100%);
}

/* The icon in its warm disc. `flex: none` so a long note can never squash it
   into an ellipse — the failure mode of every icon-beside-text row. */
/*
 * THE DISC IS RESTRAINED AND THE LINE IS NAVY.
 *
 * At 56px with a taupe stroke the discs were the heaviest thing in the card and
 * the mark inside them the lightest — a beige circle with a grey pictogram,
 * which is what made them read as a plugin's icons rather than as Lomond's.
 * 40px, a warm stone disc a shade deeper than the card so it is legible without
 * becoming a shape in its own right, and the brand navy at a 1.2 stroke.
 *
 * OPTICALLY CENTRED, NOT MATHEMATICALLY. Both marks carry more weight in their
 * lower half — the shoulders, the body of the bag — so the glyph is nudged up a
 * hair; centred on the box they sit visibly low in the circle.
 */
.lf-rwband__icon {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: #EFE7DC; color: var(--lf-navy);
  margin-top: 2px;
}
.lf-rwband__icon svg { width: 21px; height: 21px; display: block; transform: translateY(-.5px); }

.lf-rwband__copy { margin: 0; display: flex; flex-direction: column; }
.lf-rwband__lead {
  font-size: .84rem; line-height: 1.45; color: var(--lf-taupe-deep);
  margin-bottom: .28rem;
}
/* The figure is the one piece of serif in the panel, and the only thing in it
   allowed to be large — it is what the reader is meant to leave with. */
/* SIZED TO HOLD THE LONGEST FIGURE ON ONE LINE. "+500 bonus points" is the
   longest string this slot ever carries, and at 1.6rem it broke after "bonus",
   leaving the two tiles visibly unequal — a pair that no longer reads as a
   pair. `text-wrap: balance` is the backstop for a translation that is longer
   still: it splits evenly rather than orphaning a word. */
/* THE FIGURE IS THE POINT OF THE OFFER, so it is the only thing in the card
   allowed to be large. Up from 1.45rem, at the serif's 500 weight and with the
   tracking pulled in slightly — a display size set at body tracking reads as
   body copy that has been zoomed. Still sized to hold "500 bonus points" on one
   line in the narrower column this refinement gives it. */
.lf-rwband__figure {
  font-family: var(--lf-serif); font-size: clamp(1.35rem, 1.7vw, 1.6rem);
  font-weight: 500; letter-spacing: -.006em;
  line-height: 1.12; color: var(--lf-navy); margin: 0 0 .38rem;
  text-wrap: balance;
}
/* `--lf-taupe-mid` is documented as de-emphasised text only, and it measures
   3.93:1 on the panel's ivory — under the 4.5:1 this 12.8px note needs. The
   note is a condition of the offer, not decoration, so it takes `--lf-taupe`
   (7.10:1) and the de-emphasis comes from size and weight instead. */
.lf-rwband__note {
  font-size: .82rem; line-height: 1.6; color: var(--lf-taupe);
  text-wrap: pretty;
}

/* ---- the action row
   THE DIVIDER IS A BORDER ON THE LINK, not an element between the two.
   The approved composition separates the button from the text link with a thin
   vertical rule, and a rule drawn as its own element has to be hidden by hand
   the moment the row wraps — one more thing to get wrong. A border on the
   second item disappears with the row it sits in and reappears with it, and it
   takes the link's own 44px height, so it matches the button without a fixed
   height anywhere. Dropped below 600px, where the two controls stack. */
.lf-rwband__actions {
  display: flex; align-items: center; gap: clamp(1rem, 2vw, 1.75rem);
  flex-wrap: wrap; margin: clamp(1rem, 1.5vw, 1.25rem) 0 0;
}
/* The separator: a short hairline, centred on the action row, fading at both
   ends like the one between the offers, so the card has one vocabulary for
   "these are two things". A flex item, so the row's own gap supplies the space
   either side and nothing needs a padding of its own. */
.lf-rwband__sep {
  flex: none; width: 1px; height: 30px;
  background: linear-gradient(to bottom,
    rgba(141, 106, 58, 0), rgba(141, 106, 58, .28), rgba(141, 106, 58, 0));
}
/*
 * THE SEPARATOR ANSWERS TO THE CARD, NOT THE WINDOW.
 *
 * Whether the button and the link fit on one row is a question about the CARD's
 * width, and the card's width does not track the viewport's — the band goes
 * from three columns to two to one underneath it. Measured across the range,
 * the row needs about 490px of card content; below that it wrapped, the
 * separator was stranded on a line of its own above the link, and the band grew
 * 70px between 1181 and 1230 for no reason a reader could see.
 *
 * Removing it below that threshold takes the 1px AND one of the row's gaps with
 * it, which is enough to keep the row on ONE line rather than merely tidying up
 * after it has broken. The media query stays as the fallback for a browser
 * without container queries, where the phone case still needs covering.
 */
@media (max-width: 600px) { .lf-rwband__sep { display: none; } }
@container (max-width: 559px) { .lf-rwband__sep { display: none; } }

/* ---- the status foot, under the one divider the composition allows */
/*
 * ONE HAIRLINE VOCABULARY IN THE CARD.
 *
 * The other two rules — between the offers, and between the button and the link
 * — are warm gold, faded at both ends. This one was a flat grey `border-top`
 * running edge to edge, which at 2x was the only hard line in the panel and the
 * one thing in it that still looked like a widget. Drawn as a background so it
 * can fade the same way, and inset so it stops short of the card's own padding.
 */
.lf-rwband__foot {
  margin-top: clamp(1rem, 1.5vw, 1.3rem);
  padding-top: clamp(.95rem, 1.4vw, 1.2rem);
  background-image: linear-gradient(to right,
    rgba(141, 106, 58, 0) 0%,
    rgba(141, 106, 58, .2) 6%,
    rgba(141, 106, 58, .2) 94%,
    rgba(141, 106, 58, 0) 100%);
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 0;
}
/* WARM, NOT NAVY-GREY. `--lf-navy-60` is a cool blue against a warm card, so
   the one genuinely secondary line in the panel was the coolest and most
   contrasting thing in it — competing with the offers it sits below. Taupe at
   7.1:1 keeps it comfortably legible and lets it recede. The address inside it
   stays navy, because that part IS actionable. */
.lf-rwband__foot .lf-signup__pending {
  margin: 0; font-size: .8rem; line-height: 1.6; color: var(--lf-taupe);
}
.lf-rwband__foot .lf-signup__pending + .lf-signup__pending { margin-top: .5rem; }
.lf-rwband__kicker {
  margin: 0; font-family: var(--lf-sans); font-size: .68rem;
  letter-spacing: .2em; text-transform: uppercase; color: var(--lf-navy);
}
.lf-rwband__bonus {
  margin: .4rem 0 0; font-family: var(--lf-serif); font-size: 1.15rem; color: var(--lf-taupe-deep);
}

/*
 * THE OFFERS STACK WHEN THE CARD IS NARROW — WHICH IS NOT THE SAME AS WHEN THE
 * VIEWPORT IS.
 *
 * A single `max-width: 1000px` got this wrong in the middle of the range. The
 * band itself changes shape twice, so the card's width is not monotonic in the
 * viewport's:
 *
 *   > 1180   three columns, card 47%      — 555px and up. Two offers fit.
 *   861-1180 two columns, card 58%        — 499px at the bottom of the range.
 *                                           Too narrow: the figure wraps.
 *   <= 860   one column, card full width  — 820px at 860, and still 490px at
 *                                           560. Two offers fit well down.
 *
 * So the narrow cases are two DISJOINT ranges, and the rule is a media query
 * list rather than one threshold. At 768 the card is 722px wide and the offers
 * had been stacking in it, which cost about 60px of band height and left half
 * the card empty.
 *
 * When they do stack the divider turns through ninety degrees rather than
 * disappearing — two stacked offers still need to read as two — keeping the
 * same faded gold hairline and the same inset from both ends.
 */
@media (max-width: 680px), (min-width: 861px) and (max-width: 1000px) {
  .lf-rwband__offers { grid-template-columns: 1fr; gap: 1.25rem; }
  .lf-rwband__offer + .lf-rwband__offer { padding-left: 0; padding-top: 1.25rem; }
  .lf-rwband__offer + .lf-rwband__offer::before {
    left: 4%; right: 4%; top: 0; bottom: auto; width: auto; height: 1px;
    background: linear-gradient(to right,
      rgba(141, 106, 58, 0) 0%,
      rgba(141, 106, 58, .22) 22%,
      rgba(141, 106, 58, .22) 78%,
      rgba(141, 106, 58, 0) 100%);
  }
}

/* No text under 14px on a phone, where reading distance is longest relative to
   the type. The note and the lead are the two that fell below it. */
@media (max-width: 860px) {
  .lf-rwband__note, .lf-rwband__lead { font-size: .875rem; }
  .lf-rwband__foot .lf-signup__pending { font-size: .875rem; }
}

/* On a phone the primary action takes the row. At 284px inside a 310px card it
   left a 26px tail that read as a mis-set button rather than as a choice, and a
   full-width target is the easier one to hit with a thumb. The secondary link
   stays exactly where it is — subordinate, left-aligned to the card's text, and
   still on its own 44px target. */
@media (max-width: 680px) {
  .lf-rwband__actions { gap: 1rem; }
  .lf-rwband__actions .lf-signup__cta { width: 100%; }
}

/* the footer panel */
.lf-signup__intro { margin: .7rem 0 0; color: var(--lf-taupe-deep); max-width: 34ch; }
.lf-signup__actions { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; margin: 0; }
.lf-signup__cta {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 52px; padding: 0 2.1rem;
  font-family: var(--lf-sans); font-size: .84rem; letter-spacing: .15em; text-transform: uppercase;
  border: 1px solid var(--lf-navy); background: var(--lf-navy); color: #fff;
  border-radius: 2px;
  transition: background .3s var(--lf-ease), border-color .3s var(--lf-ease);
}
/* The arrow is its own element, so it can move without the label moving with
   it. 3px on hover — enough to feel like a response, not enough to be an
   animation. `will-change` is deliberately absent: one transform on hover does
   not need a compositor layer held open for the life of the page. */
.lf-signup__cta > span:last-child {
  display: inline-block;
  transition: transform .3s var(--lf-ease);
}
/*
 * STANDALONE LINKS CARRY THE 44px FLOOR; INLINE ONES DO NOT.
 *
 * WCAG 2.5.5 exempts a link sitting inside a sentence — you aim at the words,
 * and enlarging it would push the line apart. It does not exempt a link that is
 * an ACTION in its own right, and the live pass measured three of those at
 * 22-23px: "How Lomond Rewards works" beside the footer's join button, the same
 * link in the account hero, and the one under the product page's buy control.
 * All three sit next to something a mis-tap would be expensive on.
 *
 * `inline-flex` with a min-height gives the target without changing the line
 * box the text sits in, so nothing moves visually.
 */
.lf-signup__link,
.lf-rw-link,
.lf-rw-earn__link {
  display: inline-flex; align-items: center; min-height: 44px;
}
/*
 * THE UNDERLINE SITS UNDER THE TEXT, NOT UNDER THE BOX.
 *
 * The link carries a 44px touch target (see above), and a `border-bottom` draws
 * on the bottom of THAT — a hairline floating 11px below the words, attached to
 * nothing. It is why the link read as unfinished rather than as quiet.
 *
 * Drawn instead as a background gradient positioned in `em`, so it tracks the
 * font size at every breakpoint and stays a couple of pixels under the
 * baseline. `background-size` then gives the hover its movement: the rule
 * extends a few percent past the word and deepens to navy, which is the whole
 * interaction — no colour change on the text, no weight shift, no reflow.
 */
.lf-signup__link {
  font-size: .82rem; color: var(--lf-taupe-deep);
  background-image: linear-gradient(rgba(101, 81, 69, .34), rgba(101, 81, 69, .34));
  background-repeat: no-repeat;
  background-position: 0 calc(50% + .72em);
  background-size: 100% 1px;
  transition: background-size .35s var(--lf-ease), background-image .3s var(--lf-ease),
              color .3s var(--lf-ease);
}

/* ================================================================== states */

/*
 * HOVER IS GATED. On a touch device a `:hover` rule sticks after a tap and
 * leaves a control looking permanently active until something else is tapped —
 * a named anti-pattern, and one that is invisible on a desktop browser.
 */
@media (hover: hover) and (pointer: fine) {
  .lf-rw-basket__apply:hover { background: var(--lf-navy-80); }
  .lf-rw-basket__remove:hover { border-color: var(--lf-navy); }
  .lf-news__row button:hover { background: var(--lf-navy-80); }
  .lf-signup__cta:hover { background: var(--lf-navy-80); border-color: var(--lf-navy-80); }
  .lf-signup__cta:hover > span:last-child { transform: translateX(3px); }
  .lf-btn--quiet:hover { background: var(--lf-navy); color: #fff; }
  .lf-rw-basket__prompt a:hover { border-bottom-color: var(--lf-navy); }
  .lf-rw-earn__link:hover,
  .lf-rw-link:hover { color: var(--lf-navy); border-bottom-color: var(--lf-navy); }
  .lf-signup__link:hover {
    color: var(--lf-navy);
    background-image: linear-gradient(var(--lf-navy), var(--lf-navy));
    background-size: 104% 1px;
  }
  .lf-rw__cta:hover { gap: 1.1rem; }
  .lf-rwp__signin:hover { border-bottom-color: currentColor; }
}

/*
 * A visible focus ring on everything this feature adds. `:focus-visible` only,
 * so a mouse click does not leave a ring behind, and offset so it never sits on
 * top of the control's own border.
 */
.lf-rw-basket__apply:focus-visible,
.lf-rw-basket__remove:focus-visible,
.lf-rw-basket__row input:focus-visible,
.lf-news__row input:focus-visible,
.lf-news__row button:focus-visible,
.lf-news__consent input:focus-visible,
.lf-signup__cta:focus-visible,
.lf-signup__link:focus-visible,
.lf-btn--quiet:focus-visible,
.lf-rw__cta:focus-visible,
.lf-rw-link:focus-visible,
.lf-rw-earn__link:focus-visible,
.lf-rwp__signin:focus-visible {
  outline: 2px solid var(--lf-navy); outline-offset: 3px;
}
.lf-rwp__hero .lf-btn:focus-visible,
.lf-rwp__hero .lf-rwp__signin:focus-visible {
  outline-color: var(--lf-white);
}

/* ============================================================= responsive */

/*
 * Checked at 1440 / 1280 / 1024 / 768 / 430 / 390 by
 * `tools/qa/rewards/shoot.mjs`, which also asserts no horizontal page overflow,
 * no touch target under 44px and no control that has grown out of proportion.
 */
@media (max-width: 1024px) {
  .lf-rwp__more-inner { grid-template-columns: 1fr; }
}
@media (max-width: 900px) {
  .lf-rw__panels { grid-template-columns: 1fr; }
  .lf-rwp__steps { grid-template-columns: 1fr; }
  .lf-rwp__step { padding: 1.35rem 1.4rem; }
}

/*
 * THE HISTORY, RESTRUCTURED FOR A PHONE.
 *
 * It was a table in a horizontally scrolling wrapper, which is the standard
 * safe answer and was the wrong one: the render pass at 390px showed the POINTS
 * column off screen, so the number the page is about was reachable only by
 * discovering a sideways scroll. Each row becomes a block instead, with the
 * figure promoted onto the first line. The `<table>` stays a real table — the
 * headers are still there for a screen reader.
 */
@media (max-width: 640px) {
  .lf-rw__tablewrap { overflow-x: visible; }
  .lf-rw__table thead {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .lf-rw__table tr {
    display: grid; grid-template-columns: 1fr auto;
    column-gap: 1rem; row-gap: .25rem; align-items: baseline;
    padding: .95rem 0; border-bottom: 1px solid var(--lf-line);
  }
  .lf-rw__table td { border: 0; padding: 0; }
  .lf-rw__table td.lf-rw__what { grid-column: 1; grid-row: 1; }
  .lf-rw__table td.lf-rw__num  { grid-column: 2; grid-row: 1; }
  .lf-rw__table td.lf-rw__when { grid-column: 1 / -1; grid-row: 2; }
}

@media (max-width: 560px) {
  .lf-rw__split { grid-template-columns: 1fr; gap: 1rem; }
  .lf-rw__split-item { padding-right: 0; }
  .lf-rw__split-item + .lf-rw__split-item {
    padding-left: 0; border-left: 0; border-top: 1px solid var(--lf-line); padding-top: 1rem;
  }
  /*
   * FLEX-BASIS IS A HEIGHT ONCE THE AXIS TURNS. Both rows stack here and both
   * inputs carry a `flex: 1 1 <rem>` tuned for the desktop row, which in a
   * column container sizes the HEIGHT — measured at ~110px before this.
   */
  .lf-rw-basket__row { flex-direction: column; }
  .lf-rw-basket__row input,
  .lf-rw-basket__apply { flex: 0 0 auto; width: 100%; }
  .lf-news__row { flex-direction: column; }
  .lf-news__row input[type="email"],
  .lf-news__row button { flex: 0 0 auto; width: 100%; }
  .lf-rw-basket__applied { flex-direction: column; align-items: flex-start; gap: .8rem; }
  .lf-rwp__cta, .lf-rwp__close { gap: 1.2rem; }
  .lf-rwp__sum { gap: .8rem; }
}

@media (max-width: 400px) {
  .lf-rw__title { gap: .35rem; }
  .lf-rw__points { font-size: 2.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .lf-rw-basket__apply, .lf-rw-basket__remove, .lf-news__row button,
  .lf-signup__cta, .lf-btn--quiet, .lf-rw__cta,
  .lf-rw-earn__link, .lf-rw-link, .lf-signup__link { transition: none; }
  /* The arrow keeps its hover COLOUR change and loses its movement — the state
     is still communicated, the motion is not. */
  .lf-signup__cta > span:last-child { transition: none; }
  .lf-signup__cta:hover > span:last-child { transform: none; }
}

/* ====================================================== the spend milestone
   On the account page only. A sentence with a quiet track under it — not a
   gamified progress widget: the number that matters is in the sentence, and the
   bar is there to make "nearly" legible at a glance, nothing more. */

.lf-rw__milestone {
  margin: 0 0 1.5rem; padding: 1rem 1.15rem;
  background: var(--lf-cream); border: 1px solid var(--lf-gold-line);
  font-size: .88rem; line-height: 1.6; color: var(--lf-taupe-deep);
}
.lf-rw__milestone--done { background: var(--lf-ivory); border-color: var(--lf-line); }
.lf-rw__milestone-track {
  display: block; height: 3px; margin-top: .85rem;
  background: var(--lf-taupe-pale); overflow: hidden;
}
.lf-rw__milestone-fill { display: block; height: 100%; background: var(--lf-gold); }

/*
 * THE BIRTHDAY BAND borrows the example band's composition wholesale — one
 * figure, centred, with a line beneath it — because the proposition has the
 * same shape. It needs one rule of its own, and only one: when the newsletter
 * band above it is switched off, this lands directly after the example band and
 * two identical cream sections would meet with no seam between them.
 */
.lf-rwp__example + .lf-rwp__birthday { background: var(--lf-white); }

/*
 * THE BIRTHDAY HELPER LINE on the account form. One rule, because the field
 * itself deliberately reuses the account form's own `form-row` markup and needs
 * nothing — only the explanatory line beneath it would otherwise read at the
 * same weight as the value the customer just typed.
 */
.lf-birthday__note {
  display: block; margin-top: .45rem;
  font-family: var(--lf-sans); font-size: .82rem; line-height: 1.6;
  color: var(--lf-taupe-deep, #655145);
}
