/* Loft.

   A furniture shop's design: wide bands, a serif voice, and photographs given
   the room they need. Mobile first, checked at 380 pixels -- every rule starts
   from one column and adds columns when there is space, never the other way
   round (T12).

   **There is not a colour, a font stack or a size in this file.** Every value is
   a custom property the store's design tokens fill in, so changing the palette
   in Settings restyles Loft and a merchant's choice is never overwritten by a
   theme's opinion (F7A P6). The properties come from `layouts/base.twig`, which
   prints the resolved tokens into `:root`.

   Nothing here fetches anything from anybody else's server: no webfont
   declaration, no stylesheet pulled in from elsewhere, no image address
   (docs/06-guvenlik.md §8). A test asserts it by looking for the words, which is
   why they are described here rather than written.

   ⚠ **Where Loft differs from Atlas it differs in the tokens it reaches for**,
   not in values of its own: wider container, the heading scale one step further
   up, `--space-loose` where Atlas uses `--space-normal`. A shop that wants Loft
   quieter changes two settings rather than a stylesheet. */

*, *::before, *::after { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-body);
    font-size: var(--text-base);
    line-height: 1.7;
    /* A long word in a narrow column is the other way a phone ends up scrolling
       sideways, and it is the one no grid rule catches. */
    overflow-wrap: break-word;
}

img { max-width: 100%; height: auto; display: block; }
/* `<picture>` is inline by default, which leaves a text baseline gap under every
   image and makes the element ignore the block layout its `<img>` is sitting in
   (F7D K4). */
picture { display: block; }
picture > img { max-width: 100%; height: auto; display: block; }

h1, h2, h3 { font-family: var(--font-heading); line-height: 1.12; margin: 0 0 .45em; font-weight: 600; }
h1 { font-size: var(--text-h1); letter-spacing: -.02em; }
h2 { font-size: var(--text-h2); letter-spacing: -.01em; }
h3 { font-size: var(--text-h4); }
p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

.muted { color: var(--color-muted); }
.small { font-size: var(--text-small); }

/* One container, one padding, everywhere. A page whose gutters disagree with
   each other reads as two pages stitched together. */
.wrap {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: 20px;
}
.wrap--narrow { max-width: 72ch; }

.band { padding-block: var(--space-normal); }
.band--hero { padding-block: var(--space-loose); }

/* The front page's opening: a statement, one line under it, one way in. Loft
   gives it the loose step and a measure short enough to read in one sweep. */
.band--hero .lede { font-size: var(--text-h4); color: var(--color-muted); max-width: 44ch; }
.band--quiet { background: var(--color-surface); }

.eyebrow {
    margin: 0 0 .7em;
    font-size: var(--text-small);
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--color-muted);
}

/* A hairline between bands, drawn out of the surface colour rather than a grey
   of its own -- so it stays visible on the ink palette and invisible nowhere. */
.rule { border: 0; border-top: 1px solid var(--color-surface); margin: 0; }

/* The top bar. Three things, and it wraps rather than shrinking: a shop name
   squeezed to three letters on a phone is worse than a shop name on its own
   line. */
.top { border-bottom: 1px solid var(--color-surface); }
.top__inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .8em;
    padding-block: var(--space-tight);
}
.brand {
    font-family: var(--font-heading);
    font-size: var(--text-h3);
    font-weight: 600;
    letter-spacing: -.01em;
    text-decoration: none;
}
.top__nav { display: flex; align-items: center; gap: 1.2em; }
.top__nav a { text-decoration: none; font-size: var(--text-small); letter-spacing: .04em; text-transform: uppercase; }
.top__nav a:hover { text-decoration: underline; }

/* The search box in the bar. `flex: 1 1 14ch` rather than a width: it takes
   what is left on a laptop and falls to its own line on a phone. */
.top__search { display: flex; gap: .4em; flex: 1 1 18ch; min-width: 16ch; max-width: 34ch; }
.top__search input { flex: 1 1 auto; min-width: 0; }

.bottom {
    border-top: 1px solid var(--color-surface);
    padding-block: var(--space-normal);
    color: var(--color-muted);
    font-size: var(--text-small);
}

/* `min(..., 100%)` on every track floor: without it a 260px minimum is 260px on
   a 200px screen, and the page scrolls sideways. */
.grid {
    display: grid;
    gap: var(--space-normal);
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}
/* Furniture wants a bigger cell than a t-shirt does. */
.grid--wide { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }

/* Left unscoped on purpose (B78, ADR-0237), and every declaration is one the
   platform's own `.card` already makes, token for token -- so the rule cannot
   change a pixel of a section it was not written for. `CardScopeTest` holds that
   claim: the day the platform's card stops saying exactly this, the test goes
   red and the scope gets added then, for a reason rather than for symmetry. */
.card {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: var(--space-tight);
}

/* Loft's own two cards, and both classes are ones the platform never draws --
   which is what keeps the rules below off a platform section's card. */
.card--point { padding: var(--space-normal); }
.card--point h2 { font-size: var(--text-h4); }
.card--product { background: transparent; padding: 0; }
.card--product a { text-decoration: none; display: block; }
.card--product img { border-radius: var(--radius); margin-bottom: .7em; }
.card--product h2 { font-size: var(--text-base); font-family: var(--font-body); font-weight: 600; margin-bottom: .3em; }

.split {
    display: grid;
    gap: var(--space-loose);
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    align-items: start;
}
.split__media { display: grid; gap: var(--space-tight); }
.split__media img { border-radius: var(--radius); }

.button {
    display: inline-block;
    padding: .8em 1.6em;
    border: 1px solid var(--color-accent);
    border-radius: var(--radius);
    background: var(--color-accent);
    color: var(--color-accent-contrast);
    font: inherit;
    letter-spacing: .02em;
    text-decoration: none;
    cursor: pointer;
}
.button--quiet {
    background: transparent;
    color: var(--color-text);
    border-color: var(--color-muted);
}

/* The keyboard gets its own state, on every interactive thing and not only on
   links. `:focus-visible` rather than `:focus` so a mouse click leaves no ring
   behind. */
a:focus-visible, .button:focus-visible, input:focus-visible, button:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

input[type="number"] {
    width: 5em;
    padding: .55em;
    border: 1px solid var(--color-muted);
    border-radius: var(--radius);
    background: var(--color-bg);
    color: inherit;
    font: inherit;
}
input[type="search"] {
    padding: .55em .8em;
    border: 1px solid var(--color-muted);
    border-radius: var(--radius);
    background: var(--color-bg);
    color: inherit;
    font: inherit;
}

.actions { margin-top: var(--space-normal); display: flex; flex-wrap: wrap; gap: .8em; }

.crumbs { font-size: var(--text-small); color: var(--color-muted); margin-bottom: var(--space-tight); }
.crumbs span { margin-inline: .4em; }

.price { font-size: var(--text-h3); margin: 0 0 .5em; font-family: var(--font-heading); }
.price--small { font-size: var(--text-base); font-family: var(--font-body); }
.price__note { display: block; font-size: var(--text-small); color: var(--color-muted); }

.price-tiers__title { font-size: var(--text-small); letter-spacing: .12em; text-transform: uppercase; color: var(--color-muted); margin-bottom: .4em; }
.price-tiers { list-style: none; margin: 0 0 var(--space-tight); padding: 0; font-size: var(--text-small); }
.price-tiers li { padding-block: .2em; }

.note { color: var(--color-muted); font-size: var(--text-small); }
.note--good { color: var(--color-accent); }

.variants { list-style: none; margin: var(--space-normal) 0 0; padding: 0; }
.variants li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .8em;
    padding-block: .7em;
    border-top: 1px solid var(--color-surface);
}
.variants form { display: flex; gap: .5em; }

.search-form { display: flex; flex-wrap: wrap; gap: .5em; align-items: center; margin-bottom: var(--space-normal); }
.search-form__label { font-size: var(--text-small); color: var(--color-muted); flex: 1 0 100%; }

.preview {
    margin: 0;
    padding: .8em 20px;
    text-align: center;
    font-size: var(--text-small);
    background: var(--color-accent);
    color: var(--color-accent-contrast);
}

.pager { display: flex; gap: 1.2em; margin-top: var(--space-normal); font-size: var(--text-small); }

/* A table is the right element for basket lines and the wrong shape for a
   phone, so below the breakpoint every row becomes a block and each cell
   carries its own label. No script, and no second markup to keep in sync. */
.lines, .totals { width: 100%; border-collapse: collapse; margin-bottom: var(--space-normal); }
.lines th, .lines td, .totals th, .totals td { text-align: left; padding: .7em 0; vertical-align: top; }
.lines thead th { font-size: var(--text-small); letter-spacing: .08em; text-transform: uppercase; color: var(--color-muted); }
.lines tbody tr { border-top: 1px solid var(--color-surface); }
.totals tr { border-top: 1px solid var(--color-surface); }
.totals .total { font-size: var(--text-h4); }
.totals td { text-align: right; }
.cart-next-tier { display: block; color: var(--color-muted); }
.cart-checkout { margin-top: var(--space-normal); }

@media (max-width: 640px) {
    .lines thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
    .lines tr { display: block; padding-block: .6em; }
    .lines td { display: flex; justify-content: space-between; gap: 1em; padding: .3em 0; }
    .lines td::before { content: attr(data-label); color: var(--color-muted); font-size: var(--text-small); }
}

/* Hidden from the eye, present for everything else. A search field whose only
   hint is a `placeholder` is a field with no name once somebody starts typing in
   it, so the label is always there -- just not drawn. `clip-path` rather than
   `display: none`, which would take it out of the accessibility tree as well. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* The keyboard's first stop, and invisible until it is reached. Off screen
   rather than `display: none`: a hidden element is not focusable at all, which
   would make this a link nobody can reach (F7D K8). */
.skip-link {
    position: absolute;
    left: 8px;
    top: 8px;
    z-index: 100;
    padding: .6em 1.2em;
    border-radius: var(--radius);
    background: var(--color-accent);
    color: var(--color-accent-contrast);
    text-decoration: none;
    transform: translateY(-200%);
}
.skip-link:focus { transform: translateY(0); }

/* Roughly a fingertip, on the things a finger actually aims at. Not on every
   link: a word inside a paragraph is not a target, and padding it to 44 pixels
   would tear the paragraph apart (WCAG 2.2, K8). */
.button, .top__nav a, .brand {
    min-height: 44px;
    min-width: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* Not a preference about taste. Everything this stylesheet animates is switched
   off for a reader who asked. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
}

/* What a reduced price looks like (F7E J4).

   Three parts, and none of them is a colour typed by hand: the badge takes the
   store's accent and the contrast colour that was measured against it (F7D K7),
   so a merchant who changes their palette gets a readable badge without anybody
   editing this file.

   The old price is struck through *and* says "was ..." in words. The line is for
   the eye; the words are for everything else, because a screen reader does not
   reliably announce `<s>` and two numbers side by side with nothing between them
   is a page that lies to a listener. */
.price__was { color: var(--color-muted); font-size: var(--text-small); margin-right: .45em; }
.price__now { font-weight: 600; }
.badge {
    display: inline-block;
    margin-left: .45em;
    padding: .15em .55em;
    border-radius: var(--radius);
    font-size: var(--text-small);
    font-weight: 600;
    letter-spacing: .04em;
    /* Not a word wrapped away from its number. */
    white-space: nowrap;
}
.badge--sale { background: var(--color-accent); color: var(--color-accent-contrast); }
.badge--campaign { background: var(--color-surface); color: var(--color-text); }
