/*
 * Portfolio page styles
 *
 * Built 2026-05-28 to match live (https://sterretroquay.com/portfolio/).
 * Every measurement verified with chrome-devtools-mcp at 1440px and 414px
 * viewports. Spec doc (sterre-theme-specs/pages/portfolio.md) was wrong
 * about the existence of an intro block, the placement of title/material
 * text inside the grid item, the taxonomy slug ("portfolio_category" vs
 * actual "work_category"), and the image source (post-thumbnail vs ACF
 * `work_image_1`). Spec has been rewritten — see callout there.
 *
 * Three sections:
 *   .portfolio-page             — main wrapper
 *   .portfolio-intro            — h6 label + intro paragraph (40% width)
 *   .filter-container           — fixed/rotated nav on left edge
 *   .portfolio-grid-container   — 3-col CSS grid, 2x2 featured items
 *   .portfolio-grid-item        — flex column: img + info block
 *
 * Image-lag, header/filter swap, and filter reload JS are Task 17.
 * Popup click + popup-navigation JS are Task 18.
 */


/* ===== MAIN WRAPPER =====
   Live's <section class="brxe-section portfolio-page"> is a flex column
   with no padding — the inner container does the spacing. */
.portfolio-page {
	display: flex;
	flex-direction: column;
	min-height: 100vh;
}


/* ===== INTRO BLOCK =====
   Live measurements at 1440px:
     - outer container: padding: 0 138.4px (Space-3xll), margin: 45.2px 0 (Space-l)
     - h6 heading: padding-left: 16px (Space-xs), font-size 12px (body-s), color --text-primary-d-6
     - intro body: padding: 90.5px 0 (Space-2xl), width: 40%, font-size 16px,
                   line-height: 32px (--Space-m), color --text-primary-d-7
   At ≤478px live drops the body width down to 100%. */
.portfolio-intro {
	width: 100%;
	/* MATCH LIVE: page-top clearance below the fixed header.
	   Live uses an empty Bricks spacer DIV above the portfolio section.
	   --Space-4xll's clamp produces exactly that height across the
	   viewport range (190px at 1440 → 147.25px at 414). */
	padding-top: var(--Space-4xll);
}

.portfolio-intro__inner {
	display: flex;
	flex-direction: column;
	align-items: flex-start;                    /* MATCH LIVE: children sit at intrinsic width on
	                                               cross axis. Without this, the h6 stretches to
	                                               the parent's full content width and the underline
	                                               runs across the whole row (Task 16 iteration 2). */
	width: 100%;
	margin: var(--Space-l) 0;                   /* 45.2px top/bottom */
	padding: 0 var(--Space-3xll);               /* 138.4px L/R at 1440 */
}

.portfolio-intro__heading {
	font-family: var(--font-body);
	font-size: var(--body-s);                   /* 12px at 1440 — h6 is overridden here */
	font-weight: 400;
	line-height: 1.4;                           /* live measured 16.8/12 = 1.4 */
	color: var(--text-primary-d-6);
	margin: 0;
	padding: 0 0 0 var(--Space-xs);             /* 16px L — visually indents to align with body */
	width: fit-content;                         /* MATCH LIVE: underline spans just the word
	                                               "Portfolio" (~63px), not the whole row (~1163px).
	                                               Belt + braces with the parent's align-items:flex-start. */
	text-transform: none;
	letter-spacing: normal;
	text-decoration: underline;
	/* No text-underline-offset — live uses browser default (auto), which
	   sits closer to the baseline. The 0.25em we had earlier created a
	   noticeably wider gap. */
}

.portfolio-intro__body {
	padding: var(--Space-2xl) 0;                /* 90.5px top/bottom */
	width: 40%;                                 /* live: width: 40% */
	max-width: 100%;
}

.portfolio-intro__body p {
	font-family: var(--font-body);
	font-size: var(--body-m);                   /* 16px */
	font-weight: 400;
	line-height: var(--Space-m);                /* 32px — matches live's .body-text rule */
	color: var(--text-primary-d-7);
	margin: 0;
}

/* Intro responsiveness — IMPROVES on live. Live keeps the body locked at 40%
   with ~120px side padding all the way down, squashing the text to ~200px at
   tablet (768px) and ~100px at 500px. We progressively widen the body and
   shrink the inner padding so the text keeps a readable measure and aligns
   with the grid below. Desktop (>991px) stays identical to live. */
@media (max-width: 991px) {
	.portfolio-intro__inner {
		padding: 0 var(--Space-xl);             /* down from Space-3xll (~120px) */
	}
	.portfolio-intro__body {
		width: 60%;
	}
}

@media (max-width: 767px) {
	.portfolio-intro__inner {
		padding: 0 var(--Space-xs);             /* align left edge with the grid */
	}
	.portfolio-intro__body {
		width: 100%;
	}
}

@media (max-width: 478px) {
	.portfolio-intro__inner {
		/* The text gets symmetric, more generous side padding (same as the
		   tablet tier) so it sits inset from the edges. The grid keeps its own
		   tight asymmetric padding — images stay close to the edges. */
		padding: 0 var(--Space-xl);
	}
}


/* ===== FILTER BAR =====
   Live's base CSS (verified by reading inline #brxe-ftezur rules in source):
     position: fixed; left: 0; top: 50%;
     transform: rotate(-90deg) translateX(-50%) translateY(-100%);  ← HIDDEN
     transform-origin: left center; z-index: 50;
     writing-mode: horizontal-tb;
     transition: transform 0.4s ease-in-out;

   The -100% translate parks the rotated strip OFF-screen above the viewport,
   so on first paint (scrollY=0) it's not visible at all. Live confirms this
   visually — no rotated labels appear in the top-left at load.

   Task 17's header/filter-swap JS toggles to translateY(100%) on scroll-down
   (filter slides in from the left edge) and back to translateY(-100%) on
   scroll-up (filter slides out). The live JS code is captured inline in
   /portfolio/ source (lines 470-520) and will be ported in Task 17.

   PREVIOUS BUG (Task 16 iteration 1): default state was translateY(100%)
   which is the JS-applied VISIBLE state — that made the rotated labels
   show on first paint, mismatched live, and pre-empted the Task 17 swap. */
.filter-container {
	position: fixed;
	left: 0;
	top: 50%;
	transform: rotate(-90deg) translateX(-50%) translateY(-100%);
	transform-origin: left center;
	z-index: var(--z-filter-bar);                /* 50 */
	writing-mode: horizontal-tb;
	transition: transform 0.4s ease-in-out;      /* match live's inline JS */
	display: flex;
	align-items: center;
	max-width: 100%;
	padding: 0;
	margin: 0;
}

.portfolio-filter {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: row;
	width: 60vh;                                 /* live: 60vh — gives the rotated strip its visual length */
	justify-content: space-evenly;
	gap: 1rem;                                   /* live: 10px — independent of token system (filter pill spacing) */
	color: var(--text-primary);
	font-family: var(--font-body);
	font-size: var(--body-s);                    /* 12px */
}

.portfolio-filter li {
	list-style: none;
	margin: 0;
	padding: 0;
}

.portfolio-filter input[type="radio"] {
	display: none !important;
}

.portfolio-filter label {
	cursor: pointer;
	padding: var(--Space-3xs) var(--Space-xs);   /* 8px 16px — close to live's 0.5rem 1rem (8px 16px) */
	display: inline-block;
	font-family: inherit;
	font-size: inherit;
}

.portfolio-filter .brx-option-text {
	color: var(--text-primary-l-3);              /* rgb(115, 115, 112) */
	text-decoration: none;
	transition: color 0.3s;
}

.portfolio-filter label:hover .brx-option-text {
	color: var(--text-primary);                  /* darken on hover */
}

.portfolio-filter .brx-option-text.brx-option-active {
	color: var(--text-primary) !important;
	text-decoration: underline !important;
	text-underline-offset: 0.25em;
}


/* ===== PORTFOLIO GRID =====
   Live measurements at 1440px:
     - display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 64px (Space-xl)
     - grid-auto-rows: 400px; grid-auto-flow: dense
     - padding: 0 128px (Space-3xl); width: 100vw
   Grid item dimensions resolve to ~352x400px in 1440 viewport.
   Hidden by default (opacity 0) and faded in by Task 17 JS — we keep it
   visible by default here so the page is usable pre-JS. */
.portfolio-grid-container {
	display: grid;
	grid-template-columns: 1fr 1fr 1fr;
	grid-auto-rows: var(--portfolio-row-height); /* 400px */
	grid-auto-flow: dense;
	gap: var(--Space-xl);                        /* 64px */
	padding: 0 var(--Space-3xl);                 /* 128px L/R */
	width: 100vw;
	max-width: 100%;
	margin: 0;
	opacity: 1;                                  /* Task 17 will start at 0 and fade in */
	transition: opacity 0.8s ease-in-out;
}

/* Each card: image on top, info block under. Live uses display: flex
   column with the .brxe-block info block taking auto height. */
.portfolio-grid-item {
	display: flex;
	flex-direction: column;
	grid-row: span 1;
	cursor: pointer;
	background: transparent;
	overflow: visible;
	margin: 0;
	padding: 0;
}

.portfolio-grid-item[data-featured="True"] {
	grid-column: span 2;
	grid-row: span 2;
}

/* The image fills the cell width and the remaining height. Live's behaviour:
   img has width: 100%, height: 100%, object-fit: cover. The flex parent's
   height is determined by grid-auto-rows (400px) and the info block claims
   ~86px at the bottom, leaving ~314px for the image. */
.portfolio-thumbnail {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	flex: 1 1 auto;
	min-height: 0;                               /* allow flex shrink so info block fits */
	transition: transform 0.1s ease-out;         /* Task 17 image-lag will write inline transform */
	will-change: transform;
	box-shadow: 1px 1px 5px 0 var(--color-surface-d-1);
}

.portfolio-grid-item:hover .portfolio-thumbnail {
	box-shadow: 1.5px 1.5px 6px 0 var(--color-surface-d-2);
}

.portfolio-grid-item:focus-visible {
	outline: 2px solid var(--text-primary);
	outline-offset: 2px;
}

/* Info block under the image.
   Live padding: 22.6px 5.6px 0 (Space-s top, Space-4xs L/R). */
.portfolio-grid-item__info {
	display: flex;
	flex-direction: column;
	padding: var(--Space-s) var(--Space-4xs) 0;
	flex: 0 0 auto;
}

.portfolio-title {
	font-family: var(--font-body);
	font-size: var(--body-s);                    /* 12px */
	font-weight: 400;
	line-height: 1.4;                            /* 16.8/12 */
	color: var(--text-primary-d-6);
	margin: 0 0 var(--Space-4xs);                /* 5.6px gap before lines */
	text-transform: none;
	letter-spacing: normal;
	text-decoration: underline;                  /* live: titles read like links — entire card is clickable */
	text-underline-offset: 0.15em;
}

.portfolio-grid-item__line {
	font-family: var(--font-body);
	font-size: var(--body-s);                    /* 12px */
	font-weight: 400;
	line-height: 1.7;                            /* live measured 20.4/12 = 1.7 */
	color: var(--text-primary);                  /* rgb(62, 62, 59) — matches live */
	margin: 0;
	padding: 0;
}

/* Hover behaviour: when the user hovers a grid item (anywhere — image
   or info area), underline the materials and dimensions lines too, so
   the whole card visually behaves as a single link. The title is
   already permanently underlined (matches live). */
.portfolio-grid-item:hover .portfolio-grid-item__line,
.portfolio-grid-item:focus-visible .portfolio-grid-item__line {
	text-decoration: underline;
	text-underline-offset: 0.15em;               /* match title's offset for visual consistency */
}


/* ===== RESPONSIVE =====
   Live breakpoints (from Bricks default + custom rules):
     ≤991px: grid drops to 2 columns
     ≤767px: grid drops to 1 column, padding shrinks, gap shrinks to Space-s,
             featured items lose their 2x2 span, image height becomes auto
     ≤478px: intro body width: 100%, grid padding asymmetric to leave room
             for the rotated filter strip on the left (live keeps Space-xl L,
             body-m R) */

@media (max-width: 991px) {
	.portfolio-grid-container {
		grid-template-columns: 1fr 1fr;
	}
}

@media (max-width: 767px) {
	.portfolio-grid-container {
		grid-template-columns: 1fr;
		grid-auto-rows: auto;
		grid-auto-flow: row;
		gap: var(--Space-s);
		padding: 0 var(--Space-xs);
	}

	.portfolio-grid-item[data-featured="True"] {
		grid-column: span 1;
		grid-row: span 1;
	}

	/* On mobile the image is allowed to size naturally (img height: auto)
	   and the info block sits below at its content height. */
	.portfolio-thumbnail {
		height: auto;
		flex: 0 0 auto;
	}
}

@media (max-width: 478px) {
	.portfolio-grid-container {
		grid-template-columns: 1fr;
		/* Asymmetric padding matches live: more space on left to clear the
		   rotated filter strip, tighter on right. */
		padding-right: var(--body-m);
		padding-left: var(--Space-xl);
	}
}
