/* ═══════════════════════════════════════════════════════════════════════════
   fp-ofc — THE PHOTO-LED OFFER CARD
   Used by: template-parts/coupon-archive/offers-day.php, top-coupons.php
   Component: inc/offer-card.php

   Two real users called the coupon archive "outdated SaaS". Measured against
   GrabOn the cause was not spacing or colour — ~70% of their page is
   photography and ~0% of ours was. A coupon is an abstract thing, a string and
   a percentage, and a page made only of abstractions reads as a database.
   This card is the fix: the photograph is the card, and everything that used
   to be the card is now caption under it.
   ═══════════════════════════════════════════════════════════════════════════ */

.fp-ofc {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--fp-slate-200);
    border-radius: var(--fp-radius-lg);
    background: var(--fp-surface);
    box-shadow: var(--fp-shadow-md);
    transition: transform var(--fp-transition), box-shadow var(--fp-transition), border-color var(--fp-transition);
}
.fp-ofc:hover {
    transform: translateY(-3px);
    box-shadow: var(--fp-shadow-lg);
    border-color: var(--fp-slate-300);
}

/* ── The photograph ───────────────────────────────────────────────────────*/
.fp-ofc-shot {
    position: relative;
    display: block;
    aspect-ratio: 8 / 5;
    overflow: hidden;
    background: var(--fp-slate-100);
}
.fp-ofc-shot img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 420ms cubic-bezier(.2,.7,.3,1);
}
.fp-ofc:hover .fp-ofc-shot img { transform: scale(1.06); }

/* A floor under the photo so white type on a pale shot stays readable. */
.fp-ofc-shot::after {
    content: "";
    position: absolute;
    inset: auto 0 0 0;
    height: 58%;
    background: linear-gradient(to top, rgba(11,10,31,.62), transparent);
    pointer-events: none;
}

/* ── The brand chip ───────────────────────────────────────────────────────
   Mark AND name. A bare coloured monogram is what a MISSING logo looks like;
   the name beside it is the thing a shopper actually scans for, and it reads
   correctly whether or not a logo file exists. */
.fp-ofc-brand {
    position: absolute;
    left: var(--fp-space-2);
    bottom: var(--fp-space-2);
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: var(--fp-space-15);
    max-width: calc(100% - var(--fp-space-8));
    padding: 3px var(--fp-space-2) 3px 3px;
    border-radius: var(--fp-radius-pill);
    background: var(--fp-surface);
    box-shadow: var(--fp-shadow-sm);
}
.fp-ofc-brand .fp-ofc-brand-mark { width: 20px; height: 20px; font-size: 11px; flex: 0 0 auto; }
.fp-ofc-brand-n {
    font-size: var(--fp-role-meta);
    font-weight: 700;
    color: var(--fp-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── The discount flag ────────────────────────────────────────────────────
   The card's loudest graphic, top-left, lime on ink. "60% OFF" is what stops
   a thumb, and it used to be grey body copy in the caption. */
.fp-ofc-flag {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 1;
    padding: var(--fp-space-15) var(--fp-space-2) var(--fp-space-2);
    border-radius: 0 0 var(--fp-radius-md) 0;
    background: var(--fp-lime);
    color: var(--fp-lime-ink);
}
.fp-ofc-flag strong {
    font-size: var(--fp-role-h3);
    font-weight: 800;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}
.fp-ofc-flag span {
    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.1em;
    opacity: .75;
}

.fp-ofc-left {
    position: absolute;
    top: var(--fp-space-2);
    right: var(--fp-space-2);
    z-index: 2;
    padding: 2px var(--fp-space-15);
    border-radius: var(--fp-radius-pill);
    background: rgba(11,10,31,.55);
    backdrop-filter: blur(4px);
    font-size: var(--fp-role-meta);
    font-weight: 700;
    color: rgba(255,255,255,.94);
    font-variant-numeric: tabular-nums;
}
.fp-ofc-left--soon { background: var(--fp-red); color: #fff; }

/* ── The caption ──────────────────────────────────────────────────────────*/
.fp-ofc-body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--fp-space-2);
    padding: var(--fp-space-3);
}

.fp-ofc-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    /* Reserved, so a one-line title and a two-line title put the buttons of
       two adjacent cards on the same baseline. */
    min-height: calc(2 * 1.3em);
    font-size: var(--fp-role-label);
    font-weight: 700;
    line-height: 1.3;
    color: var(--fp-ink);
    text-decoration: none;
}
.fp-ofc-title:hover { text-decoration: underline; text-underline-offset: 2px; }

/* The tested rate as a BADGE. Same fact as the old grey sentence, read at a
   glance instead of as a footnote — and it is the one number the category
   never prints. */
.fp-ofc-rate {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px var(--fp-space-15);
    border-radius: var(--fp-radius-pill);
    background: var(--fp-green-soft);
    color: var(--fp-green-ink);
    font-size: var(--fp-role-meta);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* ── The ticket ───────────────────────────────────────────────────────────
   The shape that says "coupon" before a word is read. Dashed rule, monospace
   value, a copy affordance. Two states, drawn differently, because half the
   pool has no code and a surface that assumes one is wrong about the
   majority of what we list. */
.fp-ofc-ticket {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--fp-space-2);
    width: 100%;
    /* FIXED height, not intrinsic. The code variant is monospace and the
       no-code variant is not, and the 3px line-height difference between them
       put the CTA buttons of two adjacent cards on different baselines —
       measured 844 vs 847 in a 2x2 grid. Both tickets are the same object in
       two states and must occupy the same box. */
    min-height: 32px;
    padding: var(--fp-space-15) var(--fp-space-2);
    border: 1px dashed var(--fp-slate-300);
    border-radius: var(--fp-radius-sm);
    background: var(--fp-slate-50);
    font-family: var(--fp-font);
    cursor: pointer;
    transition: border-color var(--fp-transition), background var(--fp-transition);
}
.fp-ofc-ticket:hover { border-color: var(--fp-ink); background: var(--fp-surface); }
.fp-ofc-ticket:focus-visible { outline: 2px solid var(--fp-ink); outline-offset: 2px; }

.fp-ofc-ticket-v {
    white-space: nowrap;
    font-family: var(--fp-font-mono);
    font-size: var(--fp-role-meta);
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--fp-ink);
}
.fp-ofc-ticket-a {
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: var(--fp-role-meta);
    font-weight: 600;
    color: var(--fp-text-muted);
    white-space: nowrap;
}
/* Copied. Written by app.js, cleared on a timer. */
.fp-ofc-ticket[data-fp-ofc-done] { border-color: var(--fp-green); background: var(--fp-green-soft); }
.fp-ofc-ticket[data-fp-ofc-done] .fp-ofc-ticket-a { color: var(--fp-green-ink); }

/* No code. Not a control, so it loses the pointer and the hover — the
   no-boxed-emphasis rule bends for the ticket shape only because the ticket IS
   the affordance; this variant is a statement wearing the same outline so the
   two states sit on one baseline. */
.fp-ofc-ticket--none {
    cursor: default;
    background: transparent;
    /* One label, centred. The code variant is a two-slot row because it has a
       value AND an action; this has neither. */
    justify-content: center;
}
.fp-ofc-ticket--none:hover { border-color: var(--fp-slate-300); background: transparent; }
.fp-ofc-ticket--none .fp-ofc-ticket-v { font-family: var(--fp-font); letter-spacing: 0; }

/* ── The CTA ──────────────────────────────────────────────────────────────
   Every reference app ends its card in a filled button. This one ended in grey
   text, which is most of why the page read as a list rather than a shop. */
.fp-ofc-go {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--fp-space-15);
    width: 100%;
    min-height: 40px;
    padding: 0 var(--fp-space-3);
    border-radius: var(--fp-radius-pill);
    background: var(--fp-ink);
    color: var(--fp-on-dark);
    font-size: var(--fp-role-label);
    font-weight: 700;
    text-decoration: none;
    transition: background var(--fp-transition), transform var(--fp-transition);
}
.fp-ofc-go:hover { background: var(--fp-lime); color: var(--fp-lime-ink); }
.fp-ofc-go:active { transform: translateY(1px); }
.fp-ofc-go:focus-visible { outline: 2px solid var(--fp-ink); outline-offset: 2px; }

/* ── The small variant, for rails ─────────────────────────────────────────*/
.fp-ofc--sm { width: 220px; flex: 0 0 220px; }

@media (min-width: 768px) {
    .fp-ofc-body { padding: var(--fp-space-4); }
    .fp-ofc-title { font-size: var(--fp-role-body); }
    .fp-ofc-flag strong { font-size: var(--fp-role-h2); }
    .fp-ofc--sm { width: 260px; flex: 0 0 260px; }
}
