/*
 * Ocean Front Guest House — global design system.
 * Hand-authored (no build step). Enqueued on the front end AND inside the block
 * editor (add_editor_style), so blocks look identical in both. Per-block
 * style.scss files consume the --of-* custom properties below.
 *
 * ══ THIS PALETTE IS THE REAL ONE ═══════════════════════════════════════════
 * Ported from the approved mockup. When it changes, replace the VALUES here and
 * leave the NAMES alone: every block's style.scss, the chrome, and the editor's
 * background picker all resolve through these names, so re-skinning the whole
 * site is a one-file edit. Renaming them is a find-and-replace across the repo.
 * Don't.
 *
 * Names are semantic (--of-dark, --of-accent), never literal ("--of-navy"), for
 * the same reason: the second brand colour is never navy.
 *
 * The --of- prefix exists so these can never collide with WordPress core or a
 * plugin's custom properties. It is the same prefix the mockup ships, on
 * purpose: two names for one colour is how a palette drifts.
 */

:root {
	/* Ported from the "Tide Book" mockup
	   (designs/oceanfront-guest-house/assets/styles.css). The mockup's token
	   names are LITERAL (--of-kelp, --of-glass); these are SEMANTIC. They are
	   mapped, never aliased: the mockup's --of-text is a FONT STACK while this
	   file's --of-text is the body INK COLOUR, so a blanket alias would be a
	   live bug. The mapping table is in docs/INIT.md. */

	/* --- Dark surfaces: hero, deep panels ("band"), footer. Kelp. --- */
	--of-dark: #163a36;             /* kelp-2 */
	--of-dark-deep: #0f2e2b;        /* kelp — deepest panels, gradients */
	--of-dark-line: #1e4944;        /* kelp-3. BORDERS AND PANEL FILLS ONLY —
	                                   never text on a dark surface. */

	/* --- Accent: low-water sand. Two versions on purpose, and you need both. --- */
	--of-accent: #d9a441;           /* sand. Accent on DARK surfaces, and for
	                                   fills, rules and icons anywhere. */
	--of-accent-deep: #b4872f;      /* derived: sand darkened for hover/gradient
	                                   ends. Not in the mockup. */
	--of-accent-soft: #efdcb8;      /* derived: sand tinted for soft fills. */
	--of-accent-ink: #7a5a12;       /* sand-ink. Accent TEXT on LIGHT surfaces
	                                   ONLY — 6.2:1 on glass. Raw --of-accent is
	                                   2.0:1 there and FAILS AA. */

	/* --- Neutrals: water over sand. --- */
	--of-tint: #d6e1db;             /* glass-deep */
	--of-tint-mid: #c6d4cd;         /* derived: one step below glass-deep */
	--of-paper: #e7eeea;            /* glass — page background */
	--of-ink: #0f2e2b;              /* primary text */
	--of-ink-soft: #3d5854;         /* ink-2 — secondary text, 6.0:1 on glass */
	--of-line: rgba(15, 46, 43, 0.18);
	--of-line-strong: rgba(15, 46, 43, 0.4); /* outlined controls, quiet buttons */
	--of-white: #f3f7f5;            /* glass-light — the mockup's lightest
	                                   surface; not pure white, on purpose. */

	/* --- Design-specific additions. These are NEW names, not renames: the
	   mockup's dark sections carry their own text and rule colours, and the
	   "gate" colour marks a fact the client has not supplied yet. --- */
	--of-water: #2a6b75;            /* secondary cool accent */
	--of-water-ink: #245c65;        /* links on glass, 5.6:1 */
	--of-ink-on-kelp: #dce7e2;      /* body text on dark, 11.6:1 */
	--of-ink-on-kelp-2: #9db8b1;    /* secondary text on dark, 6.1:1 */
	--of-accent-on-kelp: #e6b75a;   /* accent as text on dark, 7.7:1 */
	--of-line-on-kelp: rgba(220, 231, 226, 0.22);
	--of-gate: #9a4508;             /* unverified-fact placeholder */

	/* --- Semantic aliases (keep chrome + shared helpers readable) --- */
	--of-bg: var(--of-paper);
	--of-surface: var(--of-tint);
	--of-border: var(--of-line);
	--of-text: var(--of-ink);
	--of-muted: var(--of-ink-soft);
	--of-primary: var(--of-accent-ink);

	/* --- Type stacks. Young Serif + Public Sans, loaded as ONE Google Fonts
	   request from ofgh_fonts_url() in inc/enqueue.php. The same two families
	   are set in theme.json as well — WordPress emits its own global
	   `body { font-family: … }` from theme.json and it wins on the front end
	   (SETUP §9), so the two must agree. --- */
	--of-font-display: "Young Serif", "Iowan Old Style", Georgia, serif;
	--of-font-body: "Public Sans", "Helvetica Neue", Arial, sans-serif;
	--of-font-spec: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

	/* --- Type scale, straight from the mockup. Display sizes are fluid; the
	   three smaller steps are fixed, because a body size that moves with the
	   viewport is a body size nobody can predict. --- */
	--of-size-1: clamp(2.4rem, 1.3rem + 3.4vw, 3.75rem); /* h1 */
	--of-size-2: clamp(1.9rem, 1.1rem + 2.6vw, 2.9rem);  /* h2 */
	--of-size-3: 1.375rem;                               /* h3 */
	--of-size-0: 1.0625rem;                              /* body */
	--of-size-s: 0.875rem;                               /* data, captions */

	/* --- Radii. The mockup is a flat 4px throughout. --- */
	--of-r-sm: 2px;
	--of-r-md: 4px;
	--of-r-lg: 4px;
	--of-r-pill: 999px;

	/* --- Layout --- */
	--of-wrap: 1200px;
	/* The mockup scales the gutter fluidly, so there is no 1024px step. */
	--of-gutter: clamp(1.25rem, 4vw, 3rem);
	/* Aliases kept so style.css's .ofgh-container and any earlier block CSS
	   keep resolving. Both containers are the same box. */
	--of-container: var(--of-wrap);
	--of-pad: var(--of-gutter);
	--of-measure: 62ch;

	/* Sticky header height — 72px, the mockup's minimum bar. Anchor targets
	   subtract it so an in-page jump never lands with its heading tucked under
	   the bar, and the sticky tide rail parks one header plus a 20px breath
	   below it. */
	--of-header-h: 4.5rem;
	--of-sticky-top: calc(var(--of-header-h) + 20px);

	/* --- Motion --- */
	--of-ease: cubic-bezier(0.16, 1, 0.3, 1);

	/* --- Gradients / scrims. The hero scrim is what keeps type legible over a
	   photograph; tune the stops, don't delete it. The rgba values ARE
	   --of-dark-deep (#0f2e2b = 15, 46, 43) — change both together, since CSS
	   can't take an alpha of a hex custom property without color-mix(). --- */
	--of-grad-accent: linear-gradient(135deg, var(--of-accent) 0%, var(--of-accent-deep) 100%);
	--of-hero-scrim: linear-gradient(
		102deg,
		rgba(15, 46, 43, 0.95) 0%,
		rgba(15, 46, 43, 0.88) 32%,
		rgba(15, 46, 43, 0.62) 64%,
		rgba(15, 46, 43, 0.34) 100%
	);
	--of-hero-scrim-mobile: linear-gradient(
		178deg,
		rgba(15, 46, 43, 0.8) 0%,
		rgba(15, 46, 43, 0.9) 55%,
		var(--of-dark-deep) 100%
	);

	/* Scrollbar width, published by theme.js for full-bleed alignment. */
	--of-sbw: 0px;
}

/* --- Base reset (WordPress ships none of this on the front end — SETUP §8) --- */
*,
*::before,
*::after {
	box-sizing: border-box;
}

html {
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--of-bg);
	color: var(--of-text);
	font-family: var(--of-font-body);
	font-size: var(--of-size-0);
	line-height: 1.6;
	font-feature-settings: "kern" 1, "liga" 1;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	/* clip, not hidden — hidden would make <body> a scroll container and break
	   the sticky header. */
	overflow-x: clip;
}

img {
	max-width: 100%;
	height: auto;
	display: block;
}

/* THE TABULAR RULE. Every time, height, distance, rate and phone number on this
   site wears .num. A tide table whose columns wobble between rows is a broken
   table, and proportional figures are what make them wobble. */
.num {
	font-variant-numeric: tabular-nums lining-nums;
	font-feature-settings: "tnum" 1, "lnum" 1;
}

/* Reading measure. Long-form paragraphs get this; ledgers and tables do not. */
.of-measure {
	max-width: var(--of-measure);
}

/* Form controls don't inherit font-family from body — force it, or unstyled
   inputs/buttons render in the user-agent font. */
button,
input,
select,
textarea,
optgroup {
	font-family: inherit;
}

/* WEIGHT 400, AND THAT IS NOT AN OVERSIGHT. Young Serif ships a single weight,
   so any bolder value here would be SYNTHESISED by the browser — smeared
   outlines that look subtly wrong and never match the mockup. The face does
   every display job at one weight; size and scale carry the hierarchy. */
h1,
h2,
h3,
h4 {
	font-family: var(--of-font-display);
	font-weight: 400;
	line-height: 1.08;
	letter-spacing: -0.005em;
	margin: 0;
	text-wrap: balance;
}

h1 {
	font-size: var(--of-size-1);
}

h2 {
	font-size: var(--of-size-2);
}

h3 {
	font-size: var(--of-size-3);
	line-height: 1.3;
}

a {
	color: inherit;
}

:focus-visible {
	outline: 2px solid var(--of-accent);
	outline-offset: 3px;
}

::selection {
	background: var(--of-accent);
	color: var(--of-ink);
}

/* Locks page scroll while the mobile drawer is open (set by theme.js). */
.of-no-scroll {
	overflow: hidden;
}

/* Skip link — visible only when focused. Keyboard users land here first. */
.of-skip {
	position: absolute;
	left: 0.5rem;
	top: -100%;
	z-index: 100;
	padding: 0.75rem 1.1rem;
	background: var(--of-accent);
	color: var(--of-ink);
	font-weight: 600;
	font-size: 0.9rem;
	text-decoration: none;
	border-radius: var(--of-r-sm);
}

.of-skip:focus-visible {
	top: 0.5rem;
}

/* --- Layout helpers --- */
.of-container {
	width: 100%;
	max-width: var(--of-wrap);
	margin-inline: auto;
	padding-inline: var(--of-gutter);
}

.of-section {
	padding-block: 6rem;
}

@media ( min-width: 1024px ) {
	.of-section {
		padding-block: 8rem;
	}
}

/* Every section block is an in-page anchor target. Without this, a jump to
   #services lands with the heading tucked under the 5rem fixed header. */
.of-section,
.of-hero {
	scroll-margin-top: var(--of-header-h);
}

/* --- Section backgrounds. The block's `background` attribute resolves to one
   of these four, validated against a PHP allowlist before it reaches a class
   name (see inc/partials.php → ofgh_section_bg). --- */
.of-section--paper {
	background: var(--of-paper);
}

.of-section--tint {
	background: var(--of-tint);
}

.of-section--dark {
	background: var(--of-dark);
	color: var(--of-tint);
}

.of-section--dark-deep {
	background: var(--of-dark-deep);
	color: var(--of-tint);
}

.of-section--dark h2,
.of-section--dark h3,
.of-section--dark h4,
.of-section--dark-deep h2,
.of-section--dark-deep h3,
.of-section--dark-deep h4 {
	color: var(--of-white);
}

/* --- Shared text helpers --- */
/* The eyebrow spec is shared VERBATIM across all four CLB properties:
   IBM Plex Sans 600, 0.22em tracking, 0.75rem. Do not drift it. */
.of-eyebrow {
	font-family: var(--of-font-body);
	font-weight: 600;
	letter-spacing: 0.22em;
	text-transform: uppercase;
	font-size: 0.75rem;
	line-height: 1.4;
	margin: 0;
	color: var(--of-accent-ink);
}

/* The accent at full chroma only ever appears on a dark surface — on light it
   fails AA and must step down to --of-accent-ink. */
.of-section--dark .of-eyebrow,
.of-section--dark-deep .of-eyebrow,
.of-hero .of-eyebrow {
	color: var(--of-accent);
}

.of-lede {
	font-size: 1.125rem;
	color: var(--of-ink-soft);
	max-width: 62ch;
	margin: 0;
}

.of-section--dark .of-lede,
.of-section--dark-deep .of-lede {
	color: rgba(236, 234, 230, 0.82);
}

.of-rule {
	height: 1px;
	background: var(--of-line);
	border: 0;
	margin: 0;
}

.of-section--dark .of-rule,
.of-section--dark-deep .of-rule {
	background: var(--of-dark-line);
}

/* Section heading block: eyebrow + h2 + lede. Rendered by
   ofgh_section_head() on the server and <SectionHead> in the editor, so the
   two can't drift. */
.of-shead {
	max-width: 66ch;
	margin-bottom: 3.5rem;
}

.of-shead__h {
	font-size: clamp(1.9rem, 4vw, 2.9rem);
	margin-block: 0.9rem 1.2rem;
}

/* An eyebrow with no heading after it shouldn't carry the heading's bottom
   margin, and a heading with no lede shouldn't either. */
.of-shead > :last-child {
	margin-bottom: 0;
}

/* Body links: inline only, per the internal-link rule. */
.of-section p a,
.of-prose a {
	color: var(--of-accent-ink);
	text-decoration: none;
	border-bottom: 1px solid rgba(123, 86, 45, 0.35);
	transition: border-color 0.2s;
}

.of-section p a:hover,
.of-prose a:hover {
	border-bottom-color: var(--of-accent-ink);
}

.of-section--dark p a,
.of-section--dark-deep p a {
	color: var(--of-accent);
	border-bottom-color: rgba(217, 164, 65, 0.4);
}

/* Monospaced "spec data" — reference numbers, measurements, dates, small
   labels. Scope it NARROWLY. A mono face reads as data, and once it starts
   appearing on ordinary prose it stops signalling anything at all. */
.of-spec {
	font-family: var(--of-font-spec);
	letter-spacing: 0.04em;
}

/* --- Buttons ---
   .of-btn            → base
   .of-btn--accent    → the family's gradient CTA (shared across all four sites)
   .of-btn--ghost     → accent hairline on a dark surface
   .of-btn--block     → full width
   Specificity note (SETUP §8): variants are written as .of-btn.of-btn--x so a
   later `padding` shorthand can't beat an earlier `padding-inline`. */
.of-btn {
	display: inline-flex;
	align-items: center;
	gap: 0.6rem;
	padding: 1rem 1.4rem;
	font-family: var(--of-font-body);
	font-weight: 600;
	font-size: 1rem;
	line-height: 1;
	text-decoration: none;
	border: 1px solid transparent;
	border-radius: var(--of-r-md);
	cursor: pointer;
	transition: transform 0.16s var(--of-ease), box-shadow 0.16s var(--of-ease), background-color 0.16s var(--of-ease);
}

/* FLAT SAND, not the accent gradient. This is the single accent on the page and
   it is spent on the current hour, the low-water marks and the primary action;
   a gradient would make it read as decoration instead of as the one thing to
   press. Kelp text on sand is 7.4:1. */
.of-btn.of-btn--accent {
	background: var(--of-accent);
	color: var(--of-dark-deep);
	box-shadow: 0 6px 18px -8px rgba(15, 46, 43, 0.55);
}

.of-btn.of-btn--accent:hover {
	background: #e3b052;
	transform: translateY(-1px);
	box-shadow: 0 10px 22px -10px rgba(15, 46, 43, 0.6);
}

.of-btn.of-btn--accent:active {
	transform: translateY(1px);
	box-shadow: 0 2px 8px -6px rgba(15, 46, 43, 0.6);
}

/* The quiet button is OUTLINED INK on light grounds — not accent-coloured. Two
   accent buttons side by side is two primary actions, which is none. */
.of-btn.of-btn--ghost {
	background: transparent;
	color: var(--of-ink);
	border-color: var(--of-line-strong);
}

.of-btn.of-btn--ghost:hover {
	background: rgba(15, 46, 43, 0.06);
	color: var(--of-ink);
}

/* On a kelp surface the quiet button flips to its on-kelp variants. Without
   this pair the outline and label are ink-on-ink and effectively invisible. */
.of-section--dark .of-btn.of-btn--ghost,
.of-section--dark-deep .of-btn.of-btn--ghost,
.of-footer .of-btn.of-btn--ghost,
.of-mobile .of-btn.of-btn--ghost {
	color: var(--of-ink-on-kelp);
	border-color: var(--of-line-on-kelp);
}

.of-section--dark .of-btn.of-btn--ghost:hover,
.of-section--dark-deep .of-btn.of-btn--ghost:hover,
.of-footer .of-btn.of-btn--ghost:hover,
.of-mobile .of-btn.of-btn--ghost:hover {
	background: rgba(255, 255, 255, 0.08);
	color: #fff;
}

.of-btn svg {
	width: 1.05em;
	height: 1.05em;
}

.of-btn.of-btn--block {
	width: 100%;
	justify-content: center;
}

/* The arrow slides on hover. This and the accent underline are the only two
   hover effects on the site — the audience is evaluating reliability. */
.of-btn__arw {
	transition: transform 0.25s var(--of-ease);
}

.of-btn:hover .of-btn__arw {
	transform: translateX(4px);
}

/* A row of CTAs. On narrow screens they stack full-width so both are easy tap
   targets, rather than one wide button beside a narrow one. */
.of-ctas {
	display: flex;
	flex-wrap: wrap;
	gap: 1rem;
	align-items: center;
	margin-top: 2.2rem;
}

@media ( max-width: 600px ) {
	.of-ctas {
		margin-top: 1.9rem;
		gap: 0.75rem;
	}

	.of-ctas .of-btn {
		width: 100%;
		justify-content: center;
	}
}

/* --- Reduced motion. The uptime rail never animates in the first place; this
   covers reveal, hover transforms and smooth scrolling. --- */
@media ( prefers-reduced-motion: reduce ) {
	html {
		scroll-behavior: auto;
	}

	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		transition-duration: 0.01ms !important;
	}
}

/* ------------------------------------------------------------------ labels ---
   THE LABEL-NOT-EYEBROW RULE. .of-note and .of-key sit BESIDE or BELOW the
   heading they describe, never above it. Uppercase is reserved for data keys
   the printed tide tables would set in caps; it is not a section kicker.
   Shared by several blocks, so they live here rather than in one block's
   bundle. */
.of-note {
	font-size: var(--of-size-s);
	color: var(--of-ink-soft);
	margin: 0;
}

.of-section--dark .of-note,
.of-section--dark-deep .of-note {
	color: var(--of-ink-on-kelp-2);
}

.of-key {
	font-size: var(--of-size-s);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	font-weight: 500;
	color: var(--of-ink-soft);
}

.of-section--dark .of-key,
.of-section--dark-deep .of-key {
	color: var(--of-ink-on-kelp-2);
}

/* A ruled ledger, not cards: information on this site is set the way the tide
   tables set it. Shared, not block-scoped: ofgh/house and ofgh/bread (full
   layout) both set their rows this way, and a block stylesheet is only present
   on pages that carry that block. */
.of-facts {
	list-style: none;
	margin: 2rem 0 0;
	padding: 0;
	border-top: 1px solid var(--of-line);
}

.of-facts__row {
	display: grid;
	grid-template-columns: minmax(9rem, 12rem) 1fr;
	gap: 1rem;
	padding: 0.8rem 0;
	border-bottom: 1px solid var(--of-line);
	align-items: baseline;
}

.of-facts__row .of-key {
	padding-top: 0.15em;
}

@media ( max-width: 640px ) {
	.of-facts__row {
		grid-template-columns: 1fr;
		gap: 0.2rem;
	}
}

/* In a section head the label sits between the heading and the lede, and needs
   room on both sides or the three run together as one grey block. */
.of-shead .of-note {
	margin-top: 0.75rem;
}

.of-shead .of-note + .of-lede {
	margin-top: 1rem;
}

/* The French echo the Canadian tide tables print beside each label. Dimmed, not
   hidden: it is a nicety from the printed original, not information. */
.of-fr {
	opacity: 0.62;
}
