/*
Theme Name: Personalized Baseball
Theme URI: https://gracemerch.com
Author: Jesse Lee
Author URI: https://gracemerch.com
Description: One-page WooCommerce theme for a personalized baseball keepsake. The front page and the product page share one landing layout: gallery and one purchase card that carries the personalization form first, then the checkout in the same card once a ball is in the cart.
Version: 1.0.27
Requires at least: 6.5
Requires PHP: 8.0
License: GNU General Public License v2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: personalized-baseball
Tags: e-commerce
*/

    /* The audience is mostly 60+, so the palette carries two oranges: --orange
       is decoration only (borders, tints), --orange-dark is every orange used
       as text or as a background behind white text. The decorative orange is
       3.14:1 on paper and white on it is 3.45:1, both under the 4.5:1 that
       WCAG asks for normal text; the dark one is 5.41:1 on paper and 5.94:1
       behind white. --line is for decorative dividers, --line-strong for the
       border of a control, which needs 3:1 to be visible (WCAG 1.4.11). */
    :root {
      --ink: #1f2523;
      --muted: #4a514c;
      --paper: #f7f4ee;
      --card: #fffdf9;
      --line: #dedbd3;
      --line-strong: #8a8578;
      --green: #1d5b47;
      --green-dark: #123d31;
      --orange: #d86b3e;
      --orange-dark: #a8451d;
      --orange-darker: #8f3a15;
      --shadow: 0 20px 55px rgba(31, 37, 35, .10);
      /* Vertical rhythm, one set of values per breakpoint (the phone values are
         set in the media query at the end of this file). --space-section is the
         gap between two page sections, --space-block the gap between the three
         stacked blocks of the purchase row, --space-top the room between the top
         bar and the first block. */
      --space-section: 56px;
      --space-block: 28px;
      --space-top: 24px;
    }

    * { box-sizing: border-box; }

    /* 1rem is 18px instead of the browser default 16px, so every rem value in
       this file renders one step larger for the older audience. Rules that
       used to sit under 14px were raised by hand on top of that. */
    html { font-size: 112.5%; }

    /* Smooth scrolling is switched on by the script only for in-page anchor
       clicks. A landing that arrives with a fragment (the buy button, Edit
       details) is a fresh document, so it jumps straight to the anchor instead
       of travelling there. */
    html.pb-smooth-scroll { scroll-behavior: smooth; }

    body {
      margin: 0;
      color: var(--ink);
      background: var(--paper);
      font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
      line-height: 1.6;
    }

    button, textarea { font: inherit; }

    button { cursor: pointer; }

    a { color: var(--green-dark); text-decoration: underline; text-underline-offset: 2px; }

    .page-shell {
      width: min(1160px, calc(100% - 32px));
      margin: 0 auto;
    }

    /* One bar carries the store name and the shipping promise. The horizontal
       padding mirrors the page shell's own margins (min(1160px, 100% - 32px)),
       so on a wide screen the brand lines up with the content below it. */
    .topbar {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: center;
      gap: 4px 16px;
      padding: 12px max(16px, calc((100% - 1160px) / 2));
      color: #fff;
      background: var(--green-dark);
      font-size: .89rem;
      font-weight: 700;
      letter-spacing: .05em;
      text-align: center;
      text-transform: uppercase;
    }

    /* Wider screens put the brand at the left end and the promise at the right;
       a phone stacks them, because both do not fit side by side. */
    @media (min-width: 761px) {
      .topbar { justify-content: space-between; }
    }

    /* Sits inside the bar, so it takes the bar's white. */
    .brand {
      color: inherit;
      font-size: .89rem;
      font-weight: 900;
      letter-spacing: .12em;
      text-transform: uppercase;
    }

    .hero {
      padding: var(--space-top) 0 var(--space-section);
    }

    /* The copy is the first grid row of the purchase row, and it spans the whole
       row so the headline has the widest line the page can offer: at 1160px the
       headline fits on one line at 60px, where a 980px band would have forced it
       down to 51px. On a phone the same element is the first item of the column. */
    .hero-copy {
      grid-column: 1 / -1;
      justify-self: center;
      width: 100%;
      max-width: 100%;
      margin: 0;
      text-align: center;
    }

    .purchase-row {
      display: grid;
      /* Both columns are the same width: the gallery and the personalization
         card are two halves of one product, and a narrower card left the
         gallery looking like the main event. */
      grid-template-columns: minmax(0, 1fr) minmax(340px, 1fr);
      align-items: start;
      /* The row gap is the space between the copy, the gallery and the card —
         one tier tighter than the gaps between page sections, because those
         three are one product. The column gap keeps the wider spacing it always
         had. */
      row-gap: var(--space-block);
      column-gap: clamp(32px, 6vw, 72px);
      padding: 0;
    }

    /* Carries the #pb-shop anchor, so a landing leaves the same 20px gap the
       purchase card uses. */
    .gallery-column { min-width: 0; scroll-margin-top: 20px; }

    .eyebrow {
      margin: 0 0 16px;
      color: var(--orange-dark);
      font-size: .89rem;
      font-weight: 900;
      letter-spacing: .07em;
      text-transform: uppercase;
    }

    h1, h2, p { margin-top: 0; }

    /* The headline fits on one line: in Georgia a line needs about 19px of width
       per 1px of font size, and the copy band is min(1160px, 100% - 32px), so
       4.9vw clears it at every desktop width and 60px is what fills the widest
       band. The phone query sets its own size. */
    h1 {
      margin-bottom: 20px;
      font-family: Georgia, "Times New Roman", serif;
      font-size: min(4.9vw, 60px);
      letter-spacing: -.045em;
      line-height: 1;
    }

    /* 700px is the one-line length of this sentence (652px) plus slack. */
    .intro {
      max-width: 700px;
      margin: 0 auto 20px;
      color: var(--muted);
      font-size: 1.1rem;
    }

    .trust-row {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      gap: 10px 18px;
      color: var(--green-dark);
      font-size: .89rem;
      font-weight: 800;
    }

    .trust-row span::before {
      margin-right: 6px;
      content: "✓";
      color: var(--orange-dark);
    }

    .product-card {
      position: sticky;
      top: 20px;
      /* Anchor jumps to #purchase-form leave the same 20px gap the row uses. */
      scroll-margin-top: 20px;
      overflow: hidden;
      padding: clamp(20px, 4vw, 34px);
      border: 1px solid rgba(31, 37, 35, .10);
      border-radius: 24px;
      background: var(--card);
      box-shadow: var(--shadow);
    }

    /* Gallery frame. Outer spacing lives only on .gallery-column .product-gallery. */
    .product-gallery {
      overflow: hidden;
      background: #dce7df;
    }

    .gallery-column .product-gallery {
      margin: 28px 0 0;
      border-radius: 18px;
    }

    /* Every slide is square so switching media never changes the page height.
       Padding ratio instead of aspect-ratio, which older browsers ignore. */
    .gallery-slide {
      position: relative;
      display: none;
      place-items: center;
    }

    .gallery-slide.is-active { display: grid; }

    .gallery-image {
      padding-top: 100%;
      background: #eadfce;
    }

    /* Cover on a square source cropped the print away; contain shows the whole ball. */
    .gallery-image img {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: contain;
    }

    /* The <picture> wrapper is only a source holder: keeping it out of the box
       tree leaves the image positioned exactly as it was before. */
    .gallery-image picture { display: contents; }
    .review-photo picture { display: contents; }

    .required-mark { color: var(--orange-dark); }

    .field-error {
      margin: 8px 0 0;
      color: #a33a2b;
      font-size: .89rem;
      font-weight: 800;
    }

    .field-error[hidden] { display: none; }

    /* Errors from a rejected submission are listed at the top of the card. The
       bottom of the card is below the fold when the page comes back, which is
       where these messages used to end up. */
    .pb-error-summary {
      margin: 0 0 20px;
      padding: 14px 16px;
      border: 1px solid #e7bdb2;
      border-left: 3px solid #a33a2b;
      border-radius: 12px;
      background: #fdf1ee;
      color: #a33a2b;
    }

    .pb-error-summary-title {
      margin: 0;
      font-size: .95rem;
      font-weight: 800;
    }

    .pb-error-summary ul {
      margin: 8px 0 0;
      padding-left: 22px;
    }

    .pb-error-summary li { font-size: .95rem; }
    .pb-error-summary li + li { margin-top: 4px; }
    .pb-error-summary a { color: inherit; }

    /* The tile is square and the video source is square, so the frame always fits. */
    .video-art {
      position: relative;
      overflow: hidden;
      padding-top: 100%;
      background: linear-gradient(135deg, #163f34, #3f7861);
      color: #fff;
    }

    .video-player {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    /* Play and pause share one round button; the script swaps icon and label. */
    .video-play {
      position: absolute;
      right: 14px;
      bottom: 14px;
      z-index: 1;
      display: grid;
      width: 56px;
      height: 56px;
      place-items: center;
      border: 0;
      border-radius: 50%;
      background: var(--orange-dark);
      color: #fff;
      font-size: 1.2rem;
      line-height: 1;
      box-shadow: 0 8px 22px rgba(0, 0, 0, .2);
    }

    /* White ring: the button sits on the dark video tile, where a dark ring
       would disappear. */
    .video-play:focus-visible { outline: 3px solid #fff; outline-offset: 3px; }

    /* Thumbnail strip: a round prev/next arrow flanks six square thumbnails.
       The arrows keep a 44px hit area; on a phone they are dropped (see the
       phone query) and the thumbnails take the whole row. */
    .gallery-thumbs {
      display: grid;
      grid-template-columns: 44px repeat(6, minmax(0, 1fr)) 44px;
      gap: 8px;
      padding: 10px;
      background: rgba(255, 253, 249, .75);
    }

    .gallery-note {
      margin: 12px 0 0;
      color: var(--muted);
      font-size: .89rem;
    }

    /* Square thumbnails through a padding ratio: the strip's height never
       depends on the picture's own pixel size, and an older browser that does
       not know aspect-ratio still gets the square. */
    .gallery-thumb {
      position: relative;
      overflow: hidden;
      padding-top: 100%;
      border: 1px solid var(--line-strong);
      border-radius: 8px;
      background: var(--card);
    }

    .gallery-thumb img {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }

    /* The active thumbnail keeps a green ring: on a photo, a colour change
       alone would be lost. */
    .gallery-thumb.is-active {
      border-color: var(--green);
      box-shadow: inset 0 0 0 2px var(--green);
    }

    /* Play badge over the video thumbnail: the still picture does not say that
       the first slide moves. */
    .thumb-play {
      position: absolute;
      inset: 0;
      display: grid;
      place-items: center;
      background: rgba(22, 63, 52, .32);
      color: #fff;
      font-size: .85rem;
      text-shadow: 0 1px 4px rgba(0, 0, 0, .55);
    }

    .gallery-arrow {
      align-self: center;
      width: 44px;
      height: 44px;
      padding: 0;
      border: 1px solid var(--line-strong);
      border-radius: 50%;
      background: var(--card);
      color: var(--green-dark);
      font-size: 1.35rem;
      line-height: 1;
      box-shadow: var(--shadow);
    }

    .gallery-arrow:hover { border-color: var(--green); }

    .gallery-thumb:focus-visible,
    .gallery-arrow:focus-visible { outline: 3px solid var(--green-dark); outline-offset: 2px; }

    /* The card changes shape between the two stages, so each stage says which
       one it is. This line is also the card's heading: the product name used to
       sit here as a heading too, but the step line already names the product,
       and naming it twice costs the reader a line for nothing. */
    .pb-step {
      margin: 0 0 16px;
      color: var(--muted);
      font-size: .89rem;
      font-weight: 800;
    }

    /* Price and shipping note share one left-aligned line. */
    .price-row {
      display: flex;
      flex-wrap: wrap;
      align-items: baseline;
      gap: 4px 12px;
      margin-bottom: 20px;
    }

    .price {
      color: var(--green-dark);
      font-size: 1.4rem;
      font-weight: 900;
      white-space: nowrap;
    }

    .price-note {
      color: var(--green);
      font-size: .8rem;
      font-weight: 900;
      white-space: nowrap;
    }

    fieldset {
      margin: 0 0 22px;
      padding: 0;
      border: 0;
    }

    legend, label {
      display: block;
      margin-bottom: 10px;
      font-size: .95rem;
      font-weight: 800;
    }

    .recipient-options {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
      gap: 10px;
    }

    .recipient-option {
      position: relative;
    }

    .recipient-option input {
      position: absolute;
      opacity: 0;
    }

    .recipient-option label {
      display: flex;
      min-height: 58px;
      align-items: center;
      justify-content: center;
      margin: 0;
      padding: 10px;
      border: 1.5px solid var(--line-strong);
      border-radius: 12px;
      color: var(--ink);
      text-align: center;
      white-space: nowrap;
      transition: border-color .2s, background .2s, color .2s;
    }

    .recipient-option input:checked + label {
      border-color: var(--green);
      background: #e6f0e9;
      color: var(--green-dark);
    }

    /* Ring sits 2px off the control, so it is measured against the paper
       background (11:1) instead of against the button it surrounds. */
    .recipient-option input:focus-visible + label,
    .buy-button:focus-visible { outline: 3px solid var(--green-dark); outline-offset: 2px; }

    /* Shared look for each one-line textarea used by the personalization form. */
    .conditional-field textarea,
    .name-field textarea {
      width: 100%;
      padding: 14px 15px;
      border: 1.5px solid var(--line-strong);
      border-radius: 12px;
      outline: 0;
      background: #fff;
    }

    .conditional-field textarea:focus,
    .name-field textarea:focus { border-color: var(--green); box-shadow: 0 0 0 3px rgba(29, 91, 71, .12); }

    .conditional-field { margin: -10px 0 22px; }
    .conditional-field[hidden] { display: none; }

    /* Only the recipient name field grows and sits taller than a single line. */
    .name-field textarea {
      min-height: 56px;
      resize: vertical;
    }

    .field-hint {
      display: flex;
      justify-content: space-between;
      margin-top: 7px;
      color: var(--muted);
      font-size: .89rem;
    }

    /* The benefits section carries the divider, so the section gap is split
       around it: 24px sit under the line and the rest above it. */
    .product-details {
      padding: 0 0 calc(var(--space-section) - 24px);
    }

    .product-details h2,
    .reviews h2,
    .faq h2 {
      margin-bottom: 20px;
      font-family: Georgia, "Times New Roman", serif;
      font-size: clamp(1.8rem, 4vw, 2.5rem);
      letter-spacing: -.03em;
    }

    .details-grid {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 14px;
    }

    .detail-card {
      padding: 22px;
      border: 1px solid var(--line);
      border-radius: 16px;
      background: rgba(255, 253, 249, .55);
    }

    .detail-card h3 { margin: 0 0 8px; font-size: 1rem; }
    .detail-card p { margin: 0; color: var(--muted); font-size: .95rem; }

    /* Delivery timeline: three dated steps on one row, joined by a rule behind
       the icons (the circles carry a background, so the rule stops at each one).
       The dates come from pb_delivery_estimate(), computed at render time. */
    .delivery-timeline {
      margin-top: 14px;
      padding: 22px;
      border: 1px solid var(--line);
      border-radius: 16px;
      background: var(--card);
    }

    .delivery-steps {
      position: relative;
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      margin: 0;
      padding: 0;
      list-style: none;
    }

    .delivery-steps::before {
      content: "";
      position: absolute;
      top: 27px;
      right: 16.6%;
      left: 16.6%;
      height: 2px;
      background: var(--line-strong);
    }

    .delivery-step {
      position: relative;
      display: grid;
      justify-items: center;
      gap: 4px;
      text-align: center;
    }

    .delivery-icon {
      display: grid;
      width: 54px;
      height: 54px;
      place-items: center;
      border-radius: 50%;
      background: #eceeea;
      color: var(--green-dark);
    }

    .delivery-date {
      margin-top: 8px;
      font-weight: 800;
    }

    .delivery-label {
      color: var(--muted);
      font-size: .95rem;
    }

    .refund {
      margin-top: 14px;
      padding: 22px;
      border: 1px solid var(--line);
      border-left: 3px solid var(--orange);
      border-radius: 16px;
      background: #fff8ee;
    }

    .refund h3 { margin: 0 0 8px; font-size: 1rem; }

    .refund p {
      margin: 0 0 12px;
      color: var(--muted);
      font-size: .95rem;
    }

    .refund ul {
      margin: 0;
      padding-left: 20px;
      color: var(--muted);
      font-size: .95rem;
    }

    .refund li + li { margin-top: 6px; }

    .buy-button {
      display: block;
      width: 100%;
      padding: 18px 22px;
      border: 0;
      border-radius: 12px;
      background: var(--orange-dark);
      color: #fff;
      font-size: 1.05rem;
      font-weight: 900;
      line-height: 1.3;
      text-align: center;
      text-decoration: none;
      transition: transform .2s, background .2s;
    }

    .buy-button:hover:not(:disabled) { transform: translateY(-2px); background: var(--orange-darker); }

    .payment-icons {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      gap: 6px;
      margin: 12px 0 0;
    }

    .payment-icon {
      display: block;
      width: 48px;
      height: 30px;
    }

    .payment-helper {
      margin: 6px 0 0;
      color: var(--muted);
      font-size: .78rem;
      text-align: center;
    }

    .status {
      min-height: 20px;
      margin: 12px 0 0;
      color: var(--green-dark);
      font-size: .89rem;
      font-weight: 800;
      text-align: center;
    }

    .benefits {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 18px;
      padding: 24px 0 var(--space-section);
      border-top: 1px solid var(--line);
    }

    .benefit { padding: 12px 0; }
    .benefit-icon { margin-bottom: 8px; color: var(--orange-dark); font-size: 1.35rem; }
    .benefit h3 { margin: 0 0 5px; font-size: 1rem; }
    .benefit p { margin: 0; color: var(--muted); font-size: .95rem; }

    .reviews {
      padding: 0 0 var(--space-section);
    }

    .reviews-grid {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 18px;
    }

    .review {
      display: flex;
      flex-direction: column;
      margin: 0;
      overflow: hidden;
      border: 1px solid var(--line);
      border-radius: 16px;
      background: rgba(255, 253, 249, .55);
    }

    /* Square crop so the 9:16 phone photos do not make the cards tall and narrow.
       Padding ratio instead of aspect-ratio, which older browsers ignore. */
    .review-photo {
      position: relative;
      padding-top: 100%;
    }

    .review-photo img {
      position: absolute;
      inset: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      background: #eadfce;
    }

    .review blockquote {
      margin: 0;
      padding: 16px 18px 0;
      font-size: .95rem;
    }

    .review figcaption {
      padding: 10px 18px 18px;
      color: var(--muted);
      font-size: .89rem;
      font-weight: 800;
    }

    .faq {
      padding: 0 0 var(--space-section);
    }

    .faq-item {
      margin-bottom: 10px;
      padding: 18px 22px;
      border: 1px solid var(--line);
      border-radius: 16px;
      background: rgba(255, 253, 249, .55);
    }

    /* Padding grows the tap target: only the summary line toggles the answer. */
    .faq-item summary {
      padding: 8px 0;
      cursor: pointer;
      font-size: 1rem;
      font-weight: 800;
    }

    .faq-item summary:focus-visible { outline: 3px solid var(--green-dark); outline-offset: 2px; }

    .faq-item p {
      margin: 12px 0 0;
      color: var(--muted);
      font-size: .95rem;
    }

    .faq-quote {
      margin: 12px 0 0;
      padding: 14px 18px;
      border-left: 3px solid var(--orange);
      background: #fff8ee;
      color: var(--ink);
      font-family: Georgia, "Times New Roman", serif;
      font-size: 1.05rem;
      line-height: 1.5;
    }

    /* No width cap: the headline needs 1030px to sit on one line at its 43px,
       and the viewport-scaled size below keeps it inside the shell at every
       desktop width. The button keeps its own 360px cap and stays centred. */
    .final-cta {
      max-width: none;
      margin: 0 auto;
      padding: 0 0 var(--space-section);
      text-align: center;
    }

    .final-cta h2 {
      margin-bottom: 12px;
      font-family: Georgia, "Times New Roman", serif;
      font-size: clamp(1.7rem, 3.4vw, 2.4rem);
      letter-spacing: -.03em;
    }

    .final-cta p {
      margin-bottom: 22px;
      color: var(--muted);
      font-size: .95rem;
    }

    .final-cta .buy-button {
      max-width: 360px;
      margin: 0 auto;
    }

    footer {
      padding: 22px 16px 60px;
      border-top: 1px solid var(--line);
      color: var(--muted);
      font-size: .89rem;
      text-align: center;
    }

    .mobile-buy {
      display: none;
    }

    /* Respect visitors who ask the system for less animation. The class has
       to be matched here too: html.pb-smooth-scroll is more specific than
       plain html, so a bare html rule would not win. */
    @media (prefers-reduced-motion: reduce) {
      html.pb-smooth-scroll { scroll-behavior: auto; }
      .buy-button,
      .recipient-option label { transition: none; }
    }

    @media (max-width: 760px) {
      /* One rhythm, tighter values: the tokens at the top of this file carry the
         section, block and top spacing, so no rule below repeats a number. */
      :root {
        --space-section: 40px;
        --space-block: 16px;
        --space-top: 20px;
      }

      .page-shell { width: min(100% - 24px, 560px); }
      /* The eyebrow and the intro are dropped here rather than shortened: the
         trust row under the headline carries the same facts in fewer words, and
         the height they take is what pushes the buy button off the screen. The
         desktop band above the columns keeps both. */
      .eyebrow,
      .intro { display: none; }
      .hero-copy { margin: 0; text-align: left; }
      .trust-row { justify-content: flex-start; }
      /* One column, and the order is the document order: headline, then the
         photos, then the form. align-items is set here because the desktop grid
         rule leaves it at `start`, and in a column flex container that shrinks
         every child to its content width — the card would sit at 383px inside a
         560px column with dead space beside it. */
      .purchase-row { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-block); padding: 0; }
      .gallery-column .product-gallery { margin-top: 0; }
      /* Six thumbnails and two 44px arrows do not fit a 366px row, so the
         arrows step aside: the thumbnails are the navigation on a phone. */
      .gallery-thumbs { grid-template-columns: repeat(6, minmax(0, 1fr)); }
      .gallery-arrow { display: none; }
      h1 { font-size: clamp(2.1rem, 10.8vw, 3.6rem); }
      .product-card { position: relative; top: auto; margin-top: 0; padding: 20px; }
      .benefits { grid-template-columns: 1fr; gap: 6px; }
      .reviews-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
      .review blockquote { padding: 12px 12px 0; font-size: .95rem; }
      .review figcaption { padding: 8px 12px 12px; }
      .final-cta .buy-button { display: none; }
      .details-grid { grid-template-columns: 1fr; }
      /* The timeline keeps its three columns on a phone; the icons, the dates
         and the padding come down so "Oct 14 - 28" still fits one line. */
      .delivery-timeline { padding: 16px; }
      .delivery-steps::before { top: 22px; }
      .delivery-icon { width: 44px; height: 44px; }
      .delivery-date { font-size: .95rem; }
      .delivery-label { font-size: .85rem; }
      .benefit { display: grid; grid-template-columns: 32px 1fr; column-gap: 10px; }
      .benefit-icon { grid-row: span 2; }
      .mobile-buy { display: block; position: fixed; right: 0; bottom: 0; left: 0; z-index: 5; padding: 10px 12px; border-top: 1px solid rgba(31, 37, 35, .12); background: rgba(247, 244, 238, .94); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
      .mobile-buy .buy-button { box-shadow: 0 8px 22px rgba(216, 107, 62, .28); }
      /* The bar is fixed, so the footer reserves its height: 1.6rem is the
         button's own line box and 78px is the bar padding, the button
         padding, the top border, and 20px of clearance. Written this way the
         reserved space grows when the visitor enlarges text. */
      footer { padding-bottom: calc(1.6rem + 78px); }
    }
