/**
 * Orenda - responsive corrections.
 *
 * The only stylesheet on the site. Everything else is inline on the element,
 * exactly as the static build had it, and these rules are deliberately
 * additive so they can be read as a short, reviewable list of changes rather
 * than being scattered through 24 blocks.
 *
 * Every number here came from a measurement, not an impression.
 */

/* --- Navigation ------------------------------------------------------------
 * Measured before: at 375px the links wrapped to two lines, overlapped the
 * logo, and CONTACT sat at x=375 on a 375px viewport - off the screen, so
 * the contact page was unreachable from the nav on a phone. Tap targets were
 * 27px at phone and 19px at tablet, against a 44px accessible minimum.
 * -------------------------------------------------------------------------- */

.ofi-nav__toggle {
	display: none;
	background: none;
	border: 0;
	color: #F4F6F5;
	font-family: Montserrat, sans-serif;
	font-size: 11px;
	letter-spacing: 0.2em;
	font-weight: 700;
	cursor: pointer;
	/* 44px of target without 44px of visible chrome. */
	min-width: 44px;
	min-height: 44px;
	padding: 0 4px;
}

@media (max-width: 900px) {
	.ofi-nav__toggle {
		display: block;
		position: relative;
		z-index: 2;
	}

	.ofi-nav > div {
		position: fixed;
		inset: 0;
		z-index: 1;
		flex-direction: column;
		align-items: center;
		justify-content: center;
		gap: clamp(8px, 2vh, 20px);
		background: #050606;
		font-size: 15px;
		visibility: hidden;
		opacity: 0;
		transition: opacity .25s ease, visibility .25s;
	}

	.ofi-nav[data-open="true"] > div {
		visibility: visible;
		opacity: 1;
	}

	/* The measured fix: a real 44px target, not padding on an inline link. */
	.ofi-nav > div > a {
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 44px;
		min-width: 44px;
		padding: 0 20px;
	}

	/* The page must not scroll behind an open full-screen menu. */
	body.ofi-menu-open {
		overflow: hidden;
	}
}

/* --- Reading measure -------------------------------------------------------
 * Measured, at real rendered line boxes rather than estimates:
 *
 *   land acknowledgement, hero    191 characters per line at 1440px
 *   land acknowledgement, footer  163 characters per line at 1440px
 *   body copy                     106 characters per line at 1440px
 *
 * Only the first two are treated as defects. 106 characters is long, but it
 * comes from the 860px max-width the original design sets on those blocks -
 * that is Nolan's measure, not an accident, and narrowing it is a design
 * decision for him rather than a correction for me to make quietly.
 *
 * The acknowledgement is different: it spans the full hero as fine print and
 * has no max-width at all, so it grows without limit with the viewport. A cap
 * holds it to something readable without changing where it sits or how it
 * looks. Applied from 1200px, because the problem starts at laptop width, not
 * only on large displays.
 * -------------------------------------------------------------------------- */

/* The footer acknowledgement, same reasoning as the hero one below.
 *
 * It is the only <p> in the footer, and it was the worst case: an 11px box
 * capped to 801px against a first segment needing 1051px, so it broke into
 * three on every page and stranded "as the Esquimalt and Songhees First
 * Nations," on a line of its own. Its own inline width of min(92%, 900px)
 * was not enough either, so both that and the measure cap are overridden.
 *
 * 1400px holds the first segment at 1051px with room to spare, and 96% keeps
 * it inside the viewport down at 1200px where the media query ends. */
@media (min-width: 1200px) {
	/* The constraint is the section's 8vw of side padding: it leaves 1008px
	 * of content box at a 1200px screen, and the first segment needs 1051px.
	 * Widen the footer itself rather than repositioning the paragraph -
	 * every child of the footer is centred, so it makes no visible
	 * difference to the wordmark, the links or the credit line, and it keeps
	 * the paragraph in normal flow instead of shifted off the left edge. */
	footer {
		/* The width has to go with the margins: the footer carries an inline
		 * width:100%, which pins it to the flex container's content box, so
		 * negative margins alone just slid it sideways without making it any
		 * wider. */
		width: calc(100% + 12vw) !important;
		margin-left: -6vw !important;
		margin-right: -6vw !important;
	}

	footer p {
		width: min(1400px, 96%) !important;
		max-width: none !important;
		margin-left: auto !important;
		margin-right: auto !important;
	}
}

/* The hero acknowledgement is the exception to the measure cap above.
 *
 * The approved wording carries one <br>, so it is written to read as two
 * lines. Capping it to 110ch wrapped the first segment - 190 characters
 * needing 1307px at laptop width against 996px of box - so it broke into
 * four, with a stranded "as the Esquimalt and Songhees First Nations,"
 * sitting on its own. Splitting a land acknowledgement at an arbitrary point
 * is not a neutral typographic choice.
 *
 * Its own inline max-width of min(94%, 1720px) is enough: 1307px fits inside
 * 94% of a 1440px viewport with room to spare, and the cap keeps it sane on
 * a very wide display. Two lines from laptop width up, wrapping naturally
 * below that, where two lines is not achievable at a readable size. */
@media (min-width: 1200px) {
	#covLand {
		max-width: min(94%, 1720px) !important;
		margin-left: auto !important;
		margin-right: auto !important;
	}
}

/* --- Reduced motion --------------------------------------------------------
 * The site is almost entirely scroll-driven. Nothing here disables the
 * scroll engine - that is handled in JavaScript - but transitions and CSS
 * animations stop, which is the part CSS owns.
 * -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
	*,
	*::before,
	*::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
		scroll-behavior: auto !important;
	}
}

/* --- Focus -----------------------------------------------------------------
 * Keyboard users need to see where they are. The static build had no visible
 * focus state anywhere.
 * -------------------------------------------------------------------------- */

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible {
	outline: 2px solid #ACD1D2;
	outline-offset: 3px;
}

/* --- Requested changes, 2026-09-22 -----------------------------------------
 * These are design decisions rather than port corrections, kept together so
 * they are easy to find and easy to reverse.
 *
 * Every rule here carries !important on purpose. The markup sets these
 * properties inline, and an inline style beats a stylesheet rule no matter
 * how specific it is.
 * -------------------------------------------------------------------------- */

/* The project write-up reads as a document, not a still. White ground, dark
 * type. The pale blue section labels are unreadable on white, so they take
 * the orange the CREDITS label already uses. */
.case-body {
	background: #F4F6F5 !important;
	color: #050606 !important;
}

.case-body h3 {
	color: #050606 !important;
}

/* Body copy: the same opacity ramp as before, inverted. */
.case-body p {
	color: rgba(5, 6, 6, .88) !important;
}

/* Section labels - PROJECT OVERVIEW, SCOPE, RESULTS - and the CREDITS and
 * PROJECT FRAMES headings all land on the one accent that works on white. */
.case-body p[style*="letter-spacing:.3em"] {
	color: #B15427 !important;
}

/* The credits panel border was a pale blue at 22% - invisible on white. */
.case-body > div > div[style*="border:1px solid"] {
	border-color: rgba(5, 6, 6, .18) !important;
}

/* Tiles are links. The faint background tint alone did not read as clickable,
 * so the title takes the site's standard hover colour. */
#gallery .tile a span:last-child,
#workfeat a p:last-child {
	transition: color .18s ease;
}

#gallery .tile a:hover span:last-child,
#gallery .tile a:focus-visible span:last-child,
#workfeat a:hover p:last-child,
#workfeat a:focus-visible p:last-child {
	color: #ACD1D2 !important;
}

/* The play button sat in the top-right corner, away from where the eye goes
 * and away from where a thumb lands. Centred on the tile. */
#gallery .playbtn {
	top: 50% !important;
	left: 50% !important;
	right: auto !important;
	transform: translate(-50%, -50%);
}

/* The invite section closes every page except contact, carrying a call to
 * action and the footer. Two things unbalanced it: 14vh of padding above
 * against 8vh below, which pushed the pair upward off centre, and an 8vh
 * margin on the footer that split the two into separate halves with dead air
 * between them. Even the padding so the group is optically centred, and close
 * the split so it reads as one block.
 *
 * Matched on the presence of an inline min-height, which is what distinguishes
 * the tall variants - the home page uses 120vh, the rest 90vh. The contact page has its own shorter footer with no call to action
 * to balance against, and is deliberately left alone - it is the one that
 * already reads correctly. */
#invite[style*="min-height"] {
	/* Exactly one viewport. The home page asked for 120vh and the rest for
	 * 90vh, so centring the content inside the section put it nowhere near
	 * the centre of the screen: scrolled to the bottom of the home page the
	 * block started 67px ABOVE the viewport with 311px of dead space under
	 * it. A section the height of the screen means centred-in-section and
	 * centred-in-view are the same thing. */
	/* border-box matters here: the section is content-box by default, so
	 * min-height:100vh sized the CONTENT to a full screen and then added
	 * 144px of padding on top - a 1044px section in a 900px viewport, which
	 * is precisely the overhang that pushed the block off centre. */
	box-sizing: border-box !important;
	min-height: 100vh !important;
	padding-top: 8vh !important;
	padding-bottom: 8vh !important;
	justify-content: center !important;
}

#invite[style*="min-height"] > footer {
	margin-top: 5vh !important;
}

/* The same bug, in the four places it was never fixed.
 *
 * #invite got this treatment because its footer visibly sat off centre. The
 * cause was never specific to the footer: a section is content-box by
 * default, so min-height:100vh sizes the CONTENT to a full screen and then
 * adds the padding on top. Every section written that way is taller than the
 * window it is meant to fill, so its centred content is centred on something
 * the viewer cannot see all of - scrolling to the contact form never puts
 * the form in the middle of the screen.
 *
 * Measured at 1440x900, before and after:
 *
 *   #formact  contact form   1.42 -> 1.00 screens
 *   #network  team intro     1.52 -> 1.00
 *   #who      home           1.32 -> 1.00
 *   #work     home, process  1.28 -> 1.00
 *
 * min-height is a MINIMUM, which is what makes this safe on small screens.
 * Where the content genuinely needs more than a screen - a phone in
 * landscape, a 360px Android - the section keeps its natural height and this
 * rule changes nothing. Checked at seven viewports down to 360x640 and at
 * 844x390: no content is squeezed into the padding at any of them.
 *
 * A warning for whoever measures this next. Sections carry [data-rv] reveal
 * animations that start their children at y:40. Measure a section before its
 * reveal has run and every content box reads 40px lower than it really sits,
 * which looks exactly like content overflowing the padding. It is not. Scroll
 * the section into view, let the reveal finish, and clear the transforms
 * before trusting a number - the first pass of this fix was nearly abandoned
 * over that artefact. */
#formact[style*="min-height"],
#network[style*="min-height"],
#who[style*="min-height"],
#work[style*="min-height"] {
	box-sizing: border-box !important;
	min-height: 100vh !important;
}


/* The hero kicker is white-space:nowrap at .34em tracking, which measures
 * about 382px of text on a 375px screen - so it was clipped at both ends.
 * Tightening the tracking below 480px fits it without wrapping the line or
 * shrinking the type, which is what the nowrap is protecting. */
@media (max-width: 480px) {
	#covKick {
		letter-spacing: .2em !important;
	}
}

/* The Show Reel gallery sits on white. Nolan's call, and only there - the
 * section id exists on that page alone, so nothing else can pick this up.
 *
 * Inherited colour is the whole problem: the PROJECTS heading and the note
 * beneath the grid take their colour from the body and would have gone white
 * on white. The tile captions inherit too, but they sit over a video
 * thumbnail and have to stay light, so they are handed back explicitly. */
#gallery,
#workfeat {
	color: #050606;
}

#gallery .tile,
#workfeat .ofi-tile {
	color: #F4F6F5;
}

/* Links need saying twice. The shared stylesheet sets a{color:#F4F6F5} for
 * the whole site, and that beats anything these sections inherit - so "VIEW
 * THE SHOW REEL" stayed white on the new white ground. The id in the
 * selector outranks it; the tile links then need the id too, to win back. */
#gallery a,
#workfeat a {
	color: #050606;
}

#gallery .tile a,
#workfeat .ofi-tile a {
	color: #F4F6F5;
}

/* --- Nav dropdown, 2026-09-25 ------------------------------------------------
 *
 * Archive & Rentals hangs under Services rather than taking a sixth slot in
 * the row. On a pointer it opens on hover; :focus-within is there so the same
 * panel opens for a keyboard, which hover alone never does.
 *
 * The panel is positioned against the item, not the nav, so it stays under
 * SERVICES rather than drifting as the row reflows between breakpoints.
 */
.ofi-nav__has-sub {
	position: relative;
	display: inline-block;
}

.ofi-nav__sub {
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 1;
	display: flex;
	flex-direction: column;
	gap: 14px;
	min-width: max-content;
	margin-top: 14px;
	padding: 18px 22px;
	background: rgba(5, 6, 6, .96);
	border-top: 2px solid #B15427;
	opacity: 0;
	visibility: hidden;
	transform: translateY(-6px);
	transition: opacity .18s ease, transform .18s ease, visibility .18s;
}

/* The gap between the link and the panel would close the menu on the way
 * down to it, so the item's own hover area is extended to cover it. */
.ofi-nav__has-sub::after {
	content: "";
	position: absolute;
	top: 100%;
	left: 0;
	width: 100%;
	height: 16px;
}

.ofi-nav__has-sub:hover .ofi-nav__sub,
.ofi-nav__has-sub:focus-within .ofi-nav__sub {
	opacity: 1;
	visibility: visible;
	transform: none;
}

@media (max-width: 900px) {
	/* In the full-screen menu there is nothing to hover, so the child is
	 * simply listed under its parent, indented and quieter. */
	.ofi-nav__has-sub {
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.ofi-nav > div > .ofi-nav__has-sub > a {
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 44px;
		min-width: 44px;
		padding: 0 20px;
	}

	.ofi-nav__sub {
		position: static;
		opacity: 1;
		visibility: visible;
		transform: none;
		margin-top: 0;
		padding: 0;
		background: none;
		border-top: 0;
		align-items: center;
		gap: 0;
	}

	.ofi-nav__sub a {
		display: flex;
		align-items: center;
		justify-content: center;
		min-height: 44px;
		padding: 0 20px;
		font-size: 12px;
		color: rgba(244, 246, 245, .7);
	}

	.ofi-nav__has-sub::after {
		display: none;
	}
}

/* --- Production tiles, 2026-09-25 -------------------------------------------
 *
 * These tiles are built from a query, so they cannot use the numbered
 * data-hov attributes the rest of the site uses: the number depends on how
 * many productions exist, and adding one shifts every tile after it onto a
 * different rule. The Show Reel numbered its filter buttons h1-h4 and then
 * kept counting into the tiles, which put the first two cards on h5 and h7 -
 * both background:#B15427 - so hovering a card turned the whole card rust.
 *
 * The numbers are gone from the generated tiles. These rules replace them and
 * are keyed on what the element is rather than where it fell in the count.
 */
#gallery .playbtn:hover,
#gallery .playbtn:focus-visible,
#workfeat .playbtn:hover,
#workfeat .playbtn:focus-visible {
	background: rgba(5, 6, 6, .8) !important;
	border-color: #ACD1D2 !important;
}

/* The card itself lifts its border rather than filling with colour. */
#gallery .tile:hover,
#workfeat .ofi-tile:hover {
	border-color: rgba(172, 209, 210, .5);
}

/* The flat scrim over a case study's backdrop video.
 *
 * Sits above the vertical gradient and below the copy. The gradient still
 * shapes the falloff; this only stops the middle of the frame going clear
 * and leaving a title with nothing behind it.
 *
 * One number, every production page. Raise it if a bright cover still
 * swallows the type, lower it if a dark one reads muddy. */
.ofi-case-scrim {
	position: absolute;
	inset: 0;
	background: rgba(5, 6, 6, .25);
	pointer-events: none;
}

/* A case study's copy section: the credits stay put while the writing moves.
 *
 * Only where there are two columns to be sticky in. Below 900px the layout
 * stacks, and a card pinned to the top of a phone is a card in the way. The
 * offset clears the fixed header. */
@media (min-width: 900px) {
	.ofi-credits-card {
		position: sticky;
		top: clamp(88px, 13vh, 150px);
		align-self: flex-start;
	}
}

/* The stills, on their own screen.
 *
 * min-height rather than height: the fitter shrinks the grid to land in one
 * viewport, but stops at a readable tile. A film with a very large set grows
 * this section instead of reducing its frames to specks. */
.case-stills {
	position: relative;
	background: #050606;
	min-height: 100vh;
	display: flex;
	align-items: center;
	padding: 8vh clamp(24px, 7vw, 120px);
	box-sizing: border-box;
}

.case-stills__inner {
	width: 100%;
	display: flex;
	flex-direction: column;
	gap: 6vh;
}

/* The write-up, held at one screen.
 *
 * The section is taller than the window only to buy scroll distance; its
 * height is set by the script to match how far the copy has to travel. What
 * you see is the panel below, stuck at one screen while the writing moves
 * inside its own column and the credits stay where they are.
 *
 * This section is the light one - white ground, dark type - set further up
 * this file. Nothing here changes that. */
.case-read {
	position: sticky;
	top: 0;
	height: 100vh;
	box-sizing: border-box;
	display: flex;
	align-items: center;
	padding: 12vh clamp(24px, 7vw, 120px);
	overflow: hidden;
}

.case-read__cols {
	width: 100%;
	display: grid;
	grid-template-columns: minmax(240px, 380px) 1fr;
	gap: clamp(28px, 5vw, 80px);
	align-items: center;
	min-height: 0;
}

/* The window the copy moves behind. Nothing scrolls here in the usual sense -
 * the script moves the flow inside it - so no scrollbar and no inner scroll
 * container to fight the page on a touch screen. */
.case-read__window {
	position: relative;
	min-width: 0;
	overflow: hidden;
	max-height: 76vh;
}

.case-read__flow {
	display: flex;
	flex-direction: column;
	gap: 5vh;
	will-change: transform;
}

/* The credits border was matched by document structure further up this file,
 * and this layout changed that structure. Target the card itself so the next
 * change cannot quietly un-style it. */
.ofi-credits-card {
	border-color: rgba(5, 6, 6, .18) !important;
}

/* Phones get the section back as ordinary flow. */
@media (max-width: 899px) {
	.case-body { height: auto !important; }
	.case-read {
		position: static;
		height: auto;
		overflow: visible;
		padding: 12vh clamp(24px, 7vw, 120px);
	}
	.case-read__cols { display: flex; flex-direction: column; align-items: stretch; }
	.case-read__window { max-height: none; overflow: visible; }
	.case-read__flow { transform: none !important; }
}
