/* ==========================================================================
   PHOTOLICIOUS — COMPONENTS
   The pieces that repeat across every page: headings, buttons, the media
   mount, the marquee, chips, FAQ, filter tabs and form fields.
   ========================================================================== */

/* --- Section heading ------------------------------------------------------ */
.head { margin-block-end: clamp(18px, 2.6vw, 36px); }
.head--mid { text-align: center; }
.head h2 {
	font-size: clamp(1.8rem, 5.2vw, 4.2rem);
	text-transform: uppercase;
	max-width: 21ch;
}
.head--mid h2 { margin-inline: auto; }
.head p {
	margin: 0.9rem 0 0;
	max-width: 48ch;
	opacity: 0.72;
	font-size: clamp(0.95rem, 1.25vw, 1.1rem);
}
.head--mid p { margin-inline: auto; }

/* Arabic sets no case and no tracking; see tokens.css for the reasoning. */

/* --- Eyebrow pill --------------------------------------------------------- */
.eyebrow {
	display: inline-block;
	background: var(--chip-bg);
	color: var(--accent);
	font-family: var(--font-display);
	font-weight: 800;
	font-size: 0.64rem;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	padding: 0.55em 1.05em;
	border-radius: 100px;
	margin-block-end: clamp(12px, 1.6vw, 20px);
}

/* --- Buttons -------------------------------------------------------------- */
.cta-row {
	display: flex;
	gap: 10px;
	flex-wrap: wrap;
	margin-block-start: clamp(20px, 2.6vw, 34px);
}
.cta-row--mid { justify-content: center; }

.btn {
	display: inline-block;
	text-decoration: none;
	font-weight: 700;
	font-size: 0.8rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	padding: 1em 2.2em;
	border-radius: 100px;
	border: 2px solid var(--btn-bg);
	background: var(--btn-bg);
	color: var(--btn-ink);
	cursor: pointer;
	font-family: inherit;
	transition: background 0.2s, color 0.2s, border-color 0.2s;
}
.btn:hover {
	background: var(--btn-hov-bg);
	border-color: var(--btn-hov-bg);
	color: var(--btn-hov-ink);
}
.btn--ghost {
	background: transparent;
	color: var(--ink);
	border-color: var(--ink);
}
.btn--ghost:hover {
	background: var(--ink);
	color: var(--ground);
	border-color: var(--ink);
}

/* --- Media mount ---------------------------------------------------------- */
/* Every photo sits on a near-black plate with a hairline of padding, so the
   image reads as a mounted print rather than a raw rectangle on the ground. */
.mount {
	background: var(--mount);
	border-radius: var(--r);
	padding: clamp(7px, 0.8vw, 12px);
}
.shot {
	position: relative;
	border-radius: 15px;
	overflow: hidden;
	background: var(--media-placeholder);
	display: block;
}
.shot img,
.shot video {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
/* The archive is 121 lazy tiles down forty viewports, and each one used to
   replace its empty frame in a single frame — a row of photos popping in one
   after another. They fade up instead.

   Only the script ever adds .is-arriving, and only to a photo that has not
   landed yet, so a page with no JS — or one where it fails — shows the photo
   rather than hiding it. */
.shot img { transition: opacity 0.4s ease; }
.shot img.is-arriving { opacity: 0; }
.shot--16x9 { aspect-ratio: 16 / 9; }
.shot--4x5  { aspect-ratio: 4 / 5; }
.shot--9x16 { aspect-ratio: 9 / 16; }
.shot--1x1  { aspect-ratio: 1 / 1; }
.shot--3x4  { aspect-ratio: 3 / 4; }
.shot--video::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, transparent 60%, rgb(0 0 0 / 0.34));
	pointer-events: none;
}
/* The whole tile takes the click, so the whole tile says so. Only where there
   is a film to play: a tile still waiting on its upload shows the badge as a
   plain marker and should not offer a hand. */
.shot--video[data-video] { cursor: pointer; }
.cap {
	position: absolute;
	inset-inline-start: 14px;
	bottom: 11px;
	z-index: 2;
	font-size: 0.6rem;
	letter-spacing: 0.15em;
	text-transform: uppercase;
	font-weight: 700;
	color: rgb(255 255 255 / 0.72);
}
/* The caption and the bottom viewfinder bracket both anchor 14px from the
   inline start, so the label runs straight through the corner mark — 24x14px
   of overlap. Where the frame is present, start the caption clear of it. */
.shot:has(.corner) .cap { inset-inline-start: 46px; }

/* Play affordances. The triangle stays pointing to physical right in both
   directions — a play glyph reads as "playback", not as reading order. */
.play {
	position: absolute;
	inset: 0;
	margin: auto;
	width: clamp(54px, 5.4vw, 80px);
	height: clamp(54px, 5.4vw, 80px);
	border-radius: 50%;
	background: var(--accent);
	display: grid;
	place-items: center;
	z-index: 3;
	border: 0;
	padding: 0;
	cursor: pointer;
	box-shadow: 0 6px 26px rgb(0 0 0 / 0.35);
}
.play::after {
	content: "";
	border-left: clamp(14px, 1.5vw, 20px) solid var(--black);
	border-top: clamp(9px, 1vw, 12px) solid transparent;
	border-bottom: clamp(9px, 1vw, 12px) solid transparent;
	margin-left: 5px;
}
.vplay {
	position: absolute;
	inset: 0;
	margin: auto;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--accent);
	display: grid;
	place-items: center;
	z-index: 3;
	border: 0;
	padding: 0;
	cursor: pointer;
	box-shadow: 0 5px 18px rgb(0 0 0 / 0.35);
}
.vplay::after {
	content: "";
	border-left: 11px solid var(--black);
	border-top: 7px solid transparent;
	border-bottom: 7px solid transparent;
	margin-left: 3px;
}

/* Viewfinder corner marks. Logical insets so the frame mirrors as a unit. */
.corner span {
	position: absolute;
	z-index: 2;
	width: 24px;
	height: 24px;
	border: 3px solid var(--accent);
	opacity: 0.9;
}
.corner span:nth-child(1) { top: 14px; inset-inline-start: 14px; border-inline-end: 0; border-bottom: 0; }
.corner span:nth-child(2) { top: 14px; inset-inline-end: 14px; border-inline-start: 0; border-bottom: 0; }
.corner span:nth-child(3) { bottom: 14px; inset-inline-start: 14px; border-inline-end: 0; border-top: 0; }
.corner span:nth-child(4) { bottom: 14px; inset-inline-end: 14px; border-inline-start: 0; border-top: 0; }

/* --- Client marquee ------------------------------------------------------- */
.marq {
	background: var(--chip-bg);
	border-radius: 100px;
	overflow: hidden;
	padding: clamp(13px, 1.4vw, 18px) 0;
}
.marq ul {
	display: flex;
	gap: clamp(26px, 3.6vw, 56px);
	width: max-content;
	margin: 0;
	padding: 0;
	animation: pl-slide 34s linear infinite;
}
/* The track is duplicated once, so travelling exactly half its width loops
   seamlessly. Under RTL the flex row starts at the right, so it has to travel
   the other way or the copy tears away from the original. */
@keyframes pl-slide {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}
@keyframes pl-slide-rtl {
	from { transform: translateX(0); }
	to   { transform: translateX(50%); }
}
.marq li {
	list-style: none;
	white-space: nowrap;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: clamp(0.86rem, 1.5vw, 1.3rem);
	color: rgb(255 255 255 / 0.5);
}

/* --- Chips ---------------------------------------------------------------- */
.chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-block-start: auto;
}
.chips span {
	font-size: 0.66rem;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	font-weight: 700;
	color: var(--accent);
	border: 1px solid var(--card-line-soft);
	border-radius: 100px;
	padding: 0.5em 1em;
}

/* --- FAQ ------------------------------------------------------------------ */
.faq {
	max-width: min(880px, 100%);
	margin-inline: auto;
}
.faq details { border-top: 2px solid currentColor; }
.faq details:last-of-type { border-bottom: 2px solid currentColor; }
.faq summary {
	cursor: pointer;
	list-style: none;
	display: flex;
	align-items: baseline;
	gap: 1rem;
	justify-content: space-between;
	padding: clamp(14px, 1.8vw, 20px) 4px;
	font-family: var(--font-display);
	font-weight: 800;
	font-size: clamp(0.98rem, 1.6vw, 1.3rem);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.2em; line-height: 0.8; opacity: 0.6; }
.faq details[open] summary::after { content: "–"; }
.faq details p {
	margin: 0;
	padding: 0 4px clamp(14px, 1.8vw, 20px);
	max-width: 56ch;
	opacity: 0.75;
	font-size: 0.93rem;
}

/* --- Filter tabs ---------------------------------------------------------- */
.tabs {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-block-end: clamp(18px, 2.4vw, 32px);
}
.tabs button {
	font: inherit;
	cursor: pointer;
	font-weight: 700;
	font-size: 0.76rem;
	letter-spacing: 0.06em;
	text-transform: uppercase;
	padding: 0.7em 1.3em;
	border-radius: 100px;
	border: 2px solid var(--ink);
	background: transparent;
	color: var(--ink);
	transition: background 0.2s, color 0.2s;
}
.tabs button[aria-pressed="true"] { background: var(--ink); color: var(--ground); }

/* --- Form fields ---------------------------------------------------------- */
.field { margin-block-end: clamp(14px, 1.8vw, 22px); }
.field label {
	display: block;
	font-size: 0.7rem;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	font-weight: 700;
	opacity: 0.6;
	margin-block-end: 0.5rem;
}
.field input,
.field select,
.field textarea {
	width: 100%;
	/* The card is dark in both seasons, so the controls inside it are dark
	   too — including the popup the OS draws for a select, which appearance:
	   none does not reach. Without this the option list was white text on a
	   white list. */
	color-scheme: dark;
	background: rgb(255 255 255 / 0.06);
	color: var(--white);
	border: 1px solid rgb(255 255 255 / 0.2);
	border-radius: 12px;
	padding: 0.9em 1em;
	font-family: inherit;
	font-size: 0.95rem;
}
.field input::placeholder,
.field textarea::placeholder { color: rgb(255 255 255 / 0.4); }
.field select { appearance: none; cursor: pointer; }
.field textarea { min-height: 120px; resize: vertical; }
.field input:focus,
.field select:focus,
.field textarea:focus {
	outline: 2px solid var(--accent);
	border-color: transparent;
}
/* Validation state, surfaced by app.js on submit. */
.field.is-bad input,
.field.is-bad select,
.field.is-bad textarea { border-color: #ff6b6b; }
.field__err {
	display: block;
	margin-block-start: 0.4rem;
	font-size: 0.76rem;
	color: #ff9b9b;
}
.field:not(.is-bad) .field__err { display: none; }

/* ==========================================================================
   SMALL SCREENS
   The comp's micro-labels are set in rem, so they render at the same 9.6–10.6px
   on a phone as on a 1500px desktop — legible at arm's length on a monitor,
   not in a hand. These lift only the smallest labels, and only below the
   tablet breakpoint, so the desktop composition is exactly as drawn.
   ========================================================================== */
@media (max-width: 860px) {
	.cap { font-size: 0.72rem; }
	.eyebrow { font-size: 0.74rem; }
	.chips span { font-size: 0.74rem; }
	.tabs button { font-size: 0.82rem; }
	.field label { font-size: 0.78rem; }

	/* Filter chips are the one control a thumb has to hit repeatedly. */
	.tabs button { padding: 0.8em 1.3em; }

	/* <details> rows are the tap target — give them a full-height one. */
	.faq summary { padding-block: clamp(16px, 4vw, 22px); }
}

/* --- Pagination ----------------------------------------------------------- */
/* WordPress wraps the links in <div class="nav-links">, the same class the
   header navigation uses. Those rules paint white on a dark pill, so on the
   lime archive the page numbers came out white on lime — legible only as the
   faint "2  3  Next" that made the rest of the catalogue look absent. The
   header rules are scoped to .nav-in now; this styles the real thing. */
.pagination {
	display: flex;
	justify-content: center;
	margin-block-start: clamp(28px, 4vw, 54px);
}
.pagination .nav-links {
	display: flex;
	align-items: center;
	gap: 6px;
	flex-wrap: wrap;
}
.pagination .page-numbers {
	display: grid;
	place-items: center;
	min-inline-size: 42px;
	min-block-size: 42px;
	padding-inline: 0.7em;
	border-radius: 999px;
	border: 1px solid color-mix(in srgb, var(--ink) 22%, transparent);
	color: var(--ink);
	font-size: 0.85rem;
	font-weight: 700;
	text-decoration: none;
	line-height: 1;
}
.pagination a.page-numbers:hover { background: color-mix(in srgb, var(--ink) 10%, transparent); }
.pagination .page-numbers.current {
	background: var(--ink);
	color: var(--ground);
	border-color: var(--ink);
}
.pagination .page-numbers.dots { border-color: transparent; }

/* Landing on a card from the admin's View link must not tuck it under the
   floating header. */
.archive-case { scroll-margin-block-start: clamp(84px, 11vh, 128px); }

/* --- The brief, once it has landed --------------------------------------- */
/* The card turns into its answer where it stands. A full reload threw the
   reader back to the top of the page to find a one-line message. */
.form-card { position: relative; }
.form-card.is-sending { pointer-events: none; }
.form-card.is-sending > *:not(.form-done) { opacity: 0.45; transition: opacity 0.18s ease; }
.form-card.is-done > *:not(.form-done) { display: none; }

.form-done { display: grid; justify-items: center; gap: clamp(14px, 2vw, 22px); text-align: center;
	padding-block: clamp(18px, 4vw, 42px); }
.form-done[hidden] { display: none; }
.form-card.is-done .form-done { animation: pl-done 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both; }

.form-done__tick { inline-size: clamp(46px, 6vw, 62px); aspect-ratio: 1; border-radius: 50%;
	background: var(--accent); display: grid; place-items: center; }
.form-done__tick::after { content: ""; inline-size: 34%; block-size: 60%; margin-block-start: -12%;
	border: solid var(--on-accent); border-width: 0 3px 3px 0; transform: rotate(45deg);
	animation: pl-tick 0.3s 0.14s ease-out both; }
.form-done__msg { font-size: clamp(1.05rem, 2vw, 1.4rem); line-height: 1.35; max-inline-size: 26ch;
	margin: 0; color: var(--paper); }

@keyframes pl-done { from { opacity: 0; transform: translateY(10px) scale(0.97); } }
@keyframes pl-tick { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }

@media (prefers-reduced-motion: reduce) {
	.form-card.is-done .form-done, .form-done__tick::after { animation: none; }
}
