/* ==========================================================================
   Balfe's Bikes — reusable store page
   PROMO BANNER OPTIONS (mockup — nothing here is committed yet)

   Six candidate layouts for the advert slot above each store's visit heading,
   fed by a Citrus-Lime banner collection. Pick one, then move its block into
   gtw.css and delete the rest of this file. They are ordered here the same way
   they are ordered in banner-options.html.

   Same contract as the rest of the page: scoped under .gtw-page, gtw- prefixed,
   four brand colours, flat fills, <a> for every action, no <button>.

   The one rule shared by every option: banner copy is real HTML text sitting on
   a flat brand colour, never type baked into the uploaded image, and never text
   laid directly over a photo. Citrus-Lime crops banner images with background
   cover, so the part of the picture behind any given word changes with the
   viewport — text over the photo cannot be guaranteed to stay legible, and
   text inside the JPEG cannot be read by a screen reader, translated, or
   re-cropped. Every option below keeps the words on a solid panel.
   ========================================================================== */

.gtw-page .gtw-promo {
  padding-block: clamp(28px, 4vw, 44px);
  background: var(--gtw-white);
}

/* Nested inside a page section, the promo is part of that section rather than a
   band between two of them: the section already owns the background, the shell
   width and the vertical padding, so all this contributes is the gap down to
   whatever follows. */
.gtw-page .gtw-section .gtw-promo {
  padding-block: 0;
  margin-bottom: clamp(32px, 4vw, 48px);
  background: transparent;
}

/* Marks this as an advert rather than store information. Visually quiet, but it
   is the difference between a promotion and a claim the store is making. */
.gtw-page .gtw-promo__label {
  display: block;
  margin: 0 0 12px;
  color: var(--gtw-body);
  font-family: var(--font-heading-family);
  font-size: max(0.6875rem, 11px);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ------------------------------------------------- Live collection state -- */
/* Everything below exists because the mockup was hand-written with every field
   filled, and a banner collection is not. The layouts assume a title, a line of
   copy, an action and a picture; the CMS can supply a card with any of those
   blank, or no card at all. Each gap leaves a visible artefact unless it is
   answered here, so these are the rules that keep the live slot looking like
   the approved comp rather than only the happy path of it.
   Each depends on banner.ascx binding tight against its tags — any whitespace
   between <span> and <%# Eval %> would defeat :empty. */

/* The asp:Panel renders a bare <div> with no class of its own, so spacing for a
   second card hangs off the cards themselves. Only reachable on a slot with no
   [data-gtw-promo-order]: an ordered slot shows exactly one card, and the
   hidden cards before it are still siblings, so an unscoped rule here would
   indent the one visible card by 20px for no reason a reader could see. */
.gtw-page .gtw-promo:not([data-gtw-promo-order]) .gtw-promo__inner + .gtw-promo__inner {
  margin-top: 20px;
}

/* No card means an empty collection, and without this the section would still
   draw its "Promotion" label and its margin — a heading over nothing, above a
   gap that reads as a broken image. An unfilled or mis-numbered collection
   should leave no trace, so the whole slot goes rather than being emptied.
   Pre-:has() browsers show the bare label; that is the graceful end of this. */
.gtw-page .gtw-promo:not(:has(.gtw-promo__inner)) {
  display: none;
}

/* ------------------------------------------------- One collection, 12 stores -- */
/* The control renders the whole 12-banner collection on every store, and the
   page keeps only the card belonging to this store. Selection is by the
   platform's own "theme{DisplayOrder}" class, not :nth-child: DisplayOrder is
   the number the client assigns in the CMS, so an unpublished or reordered
   entry moves the card in the DOM without ever changing which store owns it.

   [data-gtw-promo-order] carries that same number on the page, set per store by
   the build. Read the pair as one fact — "this store is number N" — written
   once in the markup and matched once here. */
.gtw-page .gtw-promo[data-gtw-promo-order='1'] .gtw-promo__inner:not(.theme1),
.gtw-page .gtw-promo[data-gtw-promo-order='2'] .gtw-promo__inner:not(.theme2),
.gtw-page .gtw-promo[data-gtw-promo-order='3'] .gtw-promo__inner:not(.theme3),
.gtw-page .gtw-promo[data-gtw-promo-order='4'] .gtw-promo__inner:not(.theme4),
.gtw-page .gtw-promo[data-gtw-promo-order='5'] .gtw-promo__inner:not(.theme5),
.gtw-page .gtw-promo[data-gtw-promo-order='6'] .gtw-promo__inner:not(.theme6),
.gtw-page .gtw-promo[data-gtw-promo-order='7'] .gtw-promo__inner:not(.theme7),
.gtw-page .gtw-promo[data-gtw-promo-order='8'] .gtw-promo__inner:not(.theme8),
.gtw-page .gtw-promo[data-gtw-promo-order='9'] .gtw-promo__inner:not(.theme9),
.gtw-page .gtw-promo[data-gtw-promo-order='10'] .gtw-promo__inner:not(.theme10),
.gtw-page .gtw-promo[data-gtw-promo-order='11'] .gtw-promo__inner:not(.theme11),
.gtw-page .gtw-promo[data-gtw-promo-order='12'] .gtw-promo__inner:not(.theme12) {
  display: none;
}

/* The same failure the empty-collection rule answers, one step later: the
   collection has cards but none of them is this store's. Without this the slot
   would draw its "Promotion" label over twelve hidden cards, which is the
   broken-image reading again. Hiding the section means a store whose banner has
   not been filled in yet simply has no promo slot. */
.gtw-page .gtw-promo[data-gtw-promo-order='1']:not(:has(.gtw-promo__inner.theme1)),
.gtw-page .gtw-promo[data-gtw-promo-order='2']:not(:has(.gtw-promo__inner.theme2)),
.gtw-page .gtw-promo[data-gtw-promo-order='3']:not(:has(.gtw-promo__inner.theme3)),
.gtw-page .gtw-promo[data-gtw-promo-order='4']:not(:has(.gtw-promo__inner.theme4)),
.gtw-page .gtw-promo[data-gtw-promo-order='5']:not(:has(.gtw-promo__inner.theme5)),
.gtw-page .gtw-promo[data-gtw-promo-order='6']:not(:has(.gtw-promo__inner.theme6)),
.gtw-page .gtw-promo[data-gtw-promo-order='7']:not(:has(.gtw-promo__inner.theme7)),
.gtw-page .gtw-promo[data-gtw-promo-order='8']:not(:has(.gtw-promo__inner.theme8)),
.gtw-page .gtw-promo[data-gtw-promo-order='9']:not(:has(.gtw-promo__inner.theme9)),
.gtw-page .gtw-promo[data-gtw-promo-order='10']:not(:has(.gtw-promo__inner.theme10)),
.gtw-page .gtw-promo[data-gtw-promo-order='11']:not(:has(.gtw-promo__inner.theme11)),
.gtw-page .gtw-promo[data-gtw-promo-order='12']:not(:has(.gtw-promo__inner.theme12)) {
  display: none;
}

/* An empty action would otherwise paint a bare sand rectangle with no label on
   it. Hiding it costs nothing, because the whole card is already the link — the
   destination stays reachable with or without the button. */
.gtw-page .gtw-promo .gtw-btn:empty {
  display: none;
}

/* Both carry margins that would survive as stray space above the action. */
.gtw-page .gtw-promo__title:empty,
.gtw-page .gtw-promo__desc:empty {
  display: none;
}

.gtw-page .gtw-promo__img {
  display: block;
  width: 100%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

/* The banner control emits these as <span>, because the whole card is a single
   <a> and a <p> cannot live inside one. display:block is what lets them keep
   behaving like the block elements the layouts were designed around. */
.gtw-page .gtw-promo__title {
  display: block;
  margin: 0;
  font-family: var(--font-heading-family);
  font-size: clamp(1.25rem, 2.2vw, 1.75rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

.gtw-page .gtw-promo__desc {
  display: block;
  margin: 10px 0 0;
  font-size: max(0.9375rem, 13px);
  line-height: 1.5;
}

/* --------------------------------- E · Wide, image at its natural size -- */
/* Option A without the crop: the image keeps its own proportions and sets the
   height of the slot. Worth it because Citrus-Lime banner artwork is usually
   supplied as a finished composition — lettering, product, logo, all placed —
   and a hard 21:9 crop cuts straight through whatever the designer arranged.
   Here the whole piece survives at any width.

   The cost is that the height of this slot is decided by whoever uploads, not
   by the page. A 16:9 upload behaves like a banner; the square 1600×1600 that
   Citrus-Lime's own guidance recommends would render 1240px tall on desktop and
   push the entire store page below the fold. No CSS can rescue that without
   reintroducing a crop, so it has to be a rule for whoever fills the
   collection: supply this slot landscape, 16:9 or wider. */

.gtw-page .gtw-promo--natural .gtw-promo__frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--gtw-radius);
  background: var(--gtw-navy);
}

/* height auto against the width/height attributes is what preserves the
   intrinsic ratio; with the box already matching the image, object-fit has
   nothing left to do and no pixels are discarded. */
.gtw-page .gtw-promo--natural .gtw-promo__img {
  width: 100%;
  height: auto;
  aspect-ratio: auto;
  object-fit: fill;
}

.gtw-page .gtw-promo--natural .gtw-promo__panel {
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  max-width: min(46ch, 62%);
  padding: clamp(20px, 2.4vw, 30px);
  background: var(--gtw-navy);
  color: var(--gtw-white);
  border-start-end-radius: var(--gtw-radius);
}

.gtw-page .gtw-promo--natural .gtw-promo__desc {
  color: var(--gtw-body-invert);
}

/* Same stack as option A: past this width the overlay leaves too little of the
   picture, and the copy would be reading over the busiest part of it. */
@media (max-width: 720px) {
  .gtw-page .gtw-promo--natural .gtw-promo__panel {
    position: static;
    max-width: none;
    border-radius: 0;
  }
}

/* --------------------------------------------------- A · Wide, panel over -- */
/* One banner. Image is cropped hard, so the panel guarantees the words stay
   readable no matter which photo the collection serves. */

/* The ratio lives on the image, not the frame. If the frame carried it, the
   frame could not grow when the panel stops overlapping at narrow widths — it
   would keep the banner's height and clip the panel straight off. */
.gtw-page .gtw-promo--wide .gtw-promo__frame {
  position: relative;
  overflow: hidden;
  border-radius: var(--gtw-radius);
  background: var(--gtw-navy);
}

.gtw-page .gtw-promo--wide .gtw-promo__img {
  aspect-ratio: 21 / 9;
}

.gtw-page .gtw-promo--wide .gtw-promo__panel {
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 0;
  max-width: min(46ch, 62%);
  padding: clamp(20px, 2.4vw, 30px);
  background: var(--gtw-navy);
  color: var(--gtw-white);
  border-start-end-radius: var(--gtw-radius);
}

.gtw-page .gtw-promo--wide .gtw-promo__desc {
  color: var(--gtw-body-invert);
}

/* Below the panel's breakpoint the image would be doing nothing but shrinking
   the words, so the panel stops overlapping and stacks under a shallower crop. */
@media (max-width: 720px) {
  .gtw-page .gtw-promo--wide .gtw-promo__img {
    aspect-ratio: 3 / 2;
  }

  .gtw-page .gtw-promo--wide .gtw-promo__panel {
    position: static;
    max-width: none;
    border-radius: 0;
  }
}

/* ------------------------------------------------------------ B · Split -- */
/* One banner. Words and picture never overlap, so any image works and the copy
   can run longer than a single line without fighting for space. */

.gtw-page .gtw-promo--split .gtw-promo__inner {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  overflow: hidden;
  border-radius: var(--gtw-radius);
  background: var(--gtw-navy);
  color: var(--gtw-white);
}

.gtw-page .gtw-promo--split .gtw-promo__panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: clamp(24px, 3vw, 44px);
}

.gtw-page .gtw-promo--split .gtw-promo__desc {
  color: var(--gtw-body-invert);
}

.gtw-page .gtw-promo--split .gtw-promo__media {
  min-height: 100%;
  aspect-ratio: 4 / 3;
}

@media (max-width: 760px) {
  .gtw-page .gtw-promo--split .gtw-promo__inner {
    grid-template-columns: 1fr;
  }

  /* Picture first on a phone: it is what stops the thumb. */
  .gtw-page .gtw-promo--split .gtw-promo__media {
    order: -1;
    aspect-ratio: 16 / 9;
  }
}

/* ------------------------------------------------------------ C · Tiles -- */
/* Three banners. Use when the store genuinely has three things to say; three
   tiles carrying one offer split into thirds reads as filler. */

.gtw-page .gtw-promo__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
  align-items: stretch;
}

.gtw-page .gtw-promo__tile {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--gtw-line);
  border-radius: var(--gtw-radius);
  background: var(--gtw-white);
}

.gtw-page .gtw-promo__tile .gtw-promo__media {
  aspect-ratio: 16 / 9;
}

.gtw-page .gtw-promo__tile .gtw-promo__panel {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: flex-start;
  padding: clamp(18px, 2vw, 24px);
}

.gtw-page .gtw-promo__tile .gtw-promo__title {
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
}

.gtw-page .gtw-promo__tile .gtw-promo__desc {
  flex: 1;
  color: var(--gtw-body);
}

/* ------------------------------------------------------------ D · Strip -- */
/* One banner, no image at all. Cheapest to run and the least disruptive, but it
   lands directly under the opening-hours strip — two bands in a row start to
   read as site chrome rather than as a message worth reading. */

.gtw-page .gtw-promo--strip {
  padding-block: 0;
}

.gtw-page .gtw-promo--strip .gtw-promo__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 20px;
  padding: 18px var(--gtw-gutter);
  background: var(--gtw-sand);
  color: var(--gtw-navy);
  text-align: center;
}

.gtw-page .gtw-promo--strip .gtw-promo__title {
  font-size: max(0.9375rem, 13px);
  letter-spacing: 0.04em;
}

.gtw-page .gtw-promo--strip .gtw-promo__desc {
  margin: 0;
}

/* Sand is a light fill, so the button flips to navy here rather than staying
   sand-on-sand — the same swap the hero makes in reverse. */
.gtw-page .gtw-promo--strip .gtw-btn--primary {
  background: var(--gtw-navy);
  color: var(--gtw-white);
}

.gtw-page .gtw-promo--strip .gtw-btn--primary:hover,
.gtw-page .gtw-promo--strip .gtw-btn--primary:focus-visible {
  background: var(--gtw-blue);
  color: var(--gtw-white);
}

/* ----------------------------------------------------- F · Notification -- */
/* One banner, shaped like a notification: thumbnail left, message and action
   right, the whole thing about 120px tall. It is the only option that does not
   treat the picture as the message — the image is demoted to an identifying
   thumbnail, which is exactly what buys the compact height.

   The text column, not the image, sets the height. The thumbnail is absolutely
   positioned inside its cell so it contributes nothing to layout and simply
   stretches to whatever the copy needs; if it were in normal flow, a tall
   upload would drag the card back up to banner height and the shape would be
   lost. That also means this option is indifferent to what gets uploaded —
   square, portrait or landscape all crop to the same thumbnail.

   Light tint rather than navy: at this size a full-width dark band directly
   under the sand opening-hours strip reads as a second piece of site chrome. */

.gtw-page .gtw-promo--note .gtw-promo__inner {
  display: grid;
  grid-template-columns: clamp(96px, 13vw, 150px) 1fr auto;
  align-items: center;
  min-height: 112px;
  overflow: hidden;
  border: 1px solid var(--gtw-line);
  border-radius: var(--gtw-radius);
  background: var(--gtw-tint);
  color: var(--gtw-navy);
}

.gtw-page .gtw-promo--note .gtw-promo__media {
  position: relative;
  align-self: stretch;
  background: var(--gtw-navy);
}

.gtw-page .gtw-promo--note .gtw-promo__img {
  position: absolute;
  inset: 0;
}

.gtw-page .gtw-promo--note .gtw-promo__body {
  padding: 16px clamp(16px, 2vw, 24px);
}

/* Well below the shared promo title size: at notification scale a 28px heading
   would be the loudest thing on the page, above the store's own h2s. */
.gtw-page .gtw-promo--note .gtw-promo__title {
  font-size: clamp(1rem, 1.4vw, 1.1875rem);
}

.gtw-page .gtw-promo--note .gtw-promo__desc {
  margin: 5px 0 0;
  color: var(--gtw-body);
}

.gtw-page .gtw-promo--note .gtw-promo__action {
  padding-inline-end: clamp(16px, 2vw, 24px);
}

.gtw-page .gtw-promo--note .gtw-promo__action .gtw-btn {
  margin-top: 0;
  min-height: 44px;
  padding-block: 10px;
  white-space: nowrap;
}

/* The action drops under the copy rather than beside it, but the thumbnail
   stays left and spans both rows — losing it would turn this into option D. */
@media (max-width: 640px) {
  .gtw-page .gtw-promo--note .gtw-promo__inner {
    grid-template-columns: 88px 1fr;
    align-items: start;
  }

  .gtw-page .gtw-promo--note .gtw-promo__media {
    grid-row: 1 / span 2;
  }

  .gtw-page .gtw-promo--note .gtw-promo__body {
    padding-block-end: 12px;
  }

  .gtw-page .gtw-promo--note .gtw-promo__action {
    padding: 0 16px 16px;
  }
}

/* ------------------------------------------------------------- Shared -- */

/* The banner control wraps the whole card in a single <a>, so the card is the
   link. citr-misc styles every <a> with its own colour and underline, which
   would repaint the panel copy and rule a line under the title, so both are
   handed back to the panel here. Focus is left alone: .gtw-page a:focus-visible
   in gtw.css already rings it, and the ring belongs on the whole card. */
.gtw-page a.gtw-promo__inner {
  color: inherit;
  text-decoration: none;
}

/* On the navy panels the primary action flips to sand — the same swap the hero
   and the closing CTA make. gtw.css scopes that flip to .gtw-hero,
   .gtw-section--dark and .gtw-cta, and these panels are none of those, so
   without this the button keeps its default navy fill and disappears into the
   panel behind it, leaving a floating label with no button around it.
   Hover goes to white rather than bronze: bronze only reaches 3.4:1 behind
   bold text at this size.
   Option F is deliberately not in this list — its card is light, so the button
   keeps the default navy fill. */
.gtw-page .gtw-promo--natural .gtw-promo__panel .gtw-btn--primary,
.gtw-page .gtw-promo--wide .gtw-promo__panel .gtw-btn--primary,
.gtw-page .gtw-promo--split .gtw-promo__panel .gtw-btn--primary {
  background: var(--gtw-sand);
  color: var(--gtw-navy);
}

.gtw-page .gtw-promo--natural .gtw-promo__panel .gtw-btn--primary:hover,
.gtw-page .gtw-promo--natural .gtw-promo__panel .gtw-btn--primary:focus-visible,
.gtw-page .gtw-promo--wide .gtw-promo__panel .gtw-btn--primary:hover,
.gtw-page .gtw-promo--wide .gtw-promo__panel .gtw-btn--primary:focus-visible,
.gtw-page .gtw-promo--split .gtw-promo__panel .gtw-btn--primary:hover,
.gtw-page .gtw-promo--split .gtw-promo__panel .gtw-btn--primary:focus-visible {
  background: var(--gtw-white);
  color: var(--gtw-navy);
}

/* Same flip, driven from the card. The action inside the control is a <span>,
   so it can never match :hover meaningfully on its own — without this the
   button would stay inert while the rest of the card is plainly a link. */
.gtw-page .gtw-promo--natural a.gtw-promo__inner:hover .gtw-btn--primary,
.gtw-page .gtw-promo--natural a.gtw-promo__inner:focus-visible .gtw-btn--primary,
.gtw-page .gtw-promo--wide a.gtw-promo__inner:hover .gtw-btn--primary,
.gtw-page .gtw-promo--wide a.gtw-promo__inner:focus-visible .gtw-btn--primary,
.gtw-page .gtw-promo--split a.gtw-promo__inner:hover .gtw-btn--primary,
.gtw-page .gtw-promo--split a.gtw-promo__inner:focus-visible .gtw-btn--primary {
  background: var(--gtw-white);
  color: var(--gtw-navy);
}

.gtw-page .gtw-promo .gtw-btn {
  margin-top: 18px;
}

.gtw-page .gtw-promo--strip .gtw-btn {
  margin-top: 0;
  min-height: 40px;
  padding-block: 8px;
}
