/*
Theme Name: KiwiPear Studios
Theme URI: https://kiwipearstudios.com
Author: KiwiPear Studios
Author URI: https://kiwipearstudios.com
Description: A dark, type-forward block theme for a solo indie game studio. Built around the split-fruit mark: one thing, two halves — kiwi green on the left, pear gold on the right. Full Site Editing, no page builder required.
Version: 1.4.0
Requires at least: 6.5
Tested up to: 6.8
Requires PHP: 7.4
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: kiwipear
Tags: full-site-editing, block-patterns, dark, portfolio, one-column, custom-colors, custom-menu, blog
*/

/* -------------------------------------------------------------
   0. Typefaces, self-hosted

   Variable fonts, so one file per family covers every weight the site
   uses. Served from the theme rather than Google's CDN: a remote font
   sends every visitor's IP address to a third party on every page view,
   which is a disclosure the site would otherwise have to make and a
   consent question it would otherwise have to answer.

   All three are SIL Open Font License 1.1 — free to self-host and to use
   commercially. Files come from the Fontsource packages on npm.
   ------------------------------------------------------------- */

@font-face {
	font-family: "Bricolage Grotesque";
	font-style: normal;
	font-display: swap;
	font-weight: 200 800;
	src: url("assets/fonts/bricolage-grotesque-latin-wght-normal.woff2") format("woff2-variations");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
		U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
		U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "Instrument Sans";
	font-style: normal;
	font-display: swap;
	font-weight: 400 700;
	src: url("assets/fonts/instrument-sans-latin-wght-normal.woff2") format("woff2-variations");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
		U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
		U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: "JetBrains Mono";
	font-style: normal;
	font-display: swap;
	font-weight: 100 800;
	src: url("assets/fonts/jetbrains-mono-latin-wght-normal.woff2") format("woff2-variations");
	unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
		U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
		U+2215, U+FEFF, U+FFFD;
}

/* -------------------------------------------------------------
   1. Base
   ------------------------------------------------------------- */

html {
	scroll-behavior: smooth;
}

body {
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

::selection {
	background: #499607;
	color: #0b0a0d;
}

/* Visible keyboard focus everywhere. */
:where(a, button, input, textarea, select, summary, .wp-block-navigation-item__content):focus-visible {
	outline: 2px solid #F78802;
	outline-offset: 3px;
	border-radius: 2px;
}

/* -------------------------------------------------------------
   2. The seam — this theme's signature device
   A hairline that runs down the exact centre of a section, the
   way the logo is cut in half. Kiwi above, pear below.
   ------------------------------------------------------------- */

.kp-seam {
	position: relative;
	isolation: isolate;
}

.kp-seam::before {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	left: 50%;
	width: 1px;
	transform: translateX(-0.5px);
	background: linear-gradient(
		to bottom,
		rgba(73, 150, 7, 0) 0%,
		rgba(73, 150, 7, 0.55) 22%,
		rgba(247, 136, 2, 0.55) 78%,
		rgba(247, 136, 2, 0) 100%
	);
	z-index: -1;
	pointer-events: none;
}

/* Two-tone wordmark: left half kiwi, right half pear, hard cut. */
.kp-split-text {
	background: linear-gradient(90deg, #499607 0%, #499607 49.9%, #F78802 50.1%, #F78802 100%);
	-webkit-background-clip: text;
	background-clip: text;
	color: transparent;
	-webkit-text-fill-color: transparent;
}

/* Mono label with a half-filled marker, echoing the split. */
/* The small mono label. Styling lives on the class, not on a heading level,
   so a label can be a paragraph or an h2 depending on what the document
   structure needs — never an h6 chosen because it happened to look right.
   The element+class selectors outrank both theme.json's heading rules and
   .wp-block-heading, whichever order they end up loading in. */
.kp-label,
h1.kp-label, h2.kp-label, h3.kp-label,
h4.kp-label, h5.kp-label, h6.kp-label,
p.kp-label {
	font-family: var(--wp--preset--font-family--utility);
	font-size: var(--wp--preset--font-size--tiny);
	font-weight: 600;
	line-height: 1.4;
	text-transform: uppercase;
	letter-spacing: 0.16em;
	color: var(--wp--preset--color--muted);
}

/* The marker is an inline-block rather than a flex child, so the label stays
   a normal block element. As inline-flex it was shrink-wrapping and ignoring
   the block's own centre alignment, which parked it on the left. */
.kp-label::before {
	content: "";
	display: inline-block;
	width: 0.7em;
	height: 0.7em;
	margin-right: 0.6em;
	vertical-align: 0.02em;
	background: linear-gradient(90deg, #499607 0%, #499607 50%, #F78802 50%, #F78802 100%);
	border-radius: 1px;
}

/* -------------------------------------------------------------
   3. Header
   ------------------------------------------------------------- */

.kp-header {
	border-bottom: 1px solid #17151a;
}

.kp-header .wp-block-site-logo img {
	display: block;
}

.kp-header .wp-block-navigation__responsive-container.is-menu-open {
	background-color: #0b0a0d;
	padding: 2.5rem 1.5rem;
}

.kp-header .wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
	color: #f6f4ec;
	font-size: 1.25rem;
}

/* -------------------------------------------------------------
   4. Cards (games, devlog entries)
   The left edge is kiwi, the right edge is pear. On hover the two
   rails grow toward each other — the fruit closing up.
   ------------------------------------------------------------- */

.kp-card {
	position: relative;
	overflow: hidden;
	background-color: #17151a;
	border: 1px solid #211e26;
	border-radius: 10px;
	transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}

.kp-card::before,
.kp-card::after {
	content: "";
	position: absolute;
	top: 0;
	bottom: 0;
	width: 2px;
	transform: scaleY(0.18);
	transform-origin: top;
	transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

.kp-card::before {
	left: 0;
	background: #499607;
}

.kp-card::after {
	right: 0;
	background: #F78802;
	transform-origin: bottom;
}

.kp-card:hover,
.kp-card:focus-within {
	transform: translateY(-3px);
	border-color: #2a262f;
	box-shadow: 0 18px 40px -24px rgba(0, 0, 0, 0.9);
}

.kp-card:hover::before,
.kp-card:hover::after,
.kp-card:focus-within::before,
.kp-card:focus-within::after {
	transform: scaleY(1);
}

/* -------------------------------------------------------------
   Key art panels. The image lives in the theme, so these classes
   work anywhere — templates, patterns, or a page you edit by hand —
   without uploading anything to the media library first.
   ------------------------------------------------------------- */

.kp-art--photon {
	background-image: url("assets/photon-ring-key-art.jpg");
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.kp-art--photon-wide {
	background-image: url("assets/photon-ring-wide.jpg");
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

/* Photon Ring: the player's object, drawn round the game's name on the home
   card. Two selectors, so it works whether or not the markup carries the
   wrapper span — a page saved before that span existed still gets the ring. */
/* The paragraph has to shrink-wrap so the circle sizes to the text, but an
   inline-block is inline-level, and auto margins do not centre inline-level
   boxes — so the container needs text-align, or the ring drifts left and the
   cover clips it. Same trap as the labels. */
.kp-card .kp-cover:not([class*="kp-art--"]) .wp-block-cover__inner-container {
	text-align: center;
}

.kp-ring,
.kp-card .kp-cover:not([class*="kp-art--"]) .wp-block-cover__inner-container p {
	position: relative;
	display: inline-block;
	text-shadow: 0 1px 10px rgba(11, 10, 13, 0.9);
}

.kp-ring::before,
.kp-ring::after,
.kp-card .kp-cover:not([class*="kp-art--"]) .wp-block-cover__inner-container p::before,
.kp-card .kp-cover:not([class*="kp-art--"]) .wp-block-cover__inner-container p::after {
	content: "";
	position: absolute;
	left: 50%;
	top: 50%;
	width: 168%;
	aspect-ratio: 1;
	transform: translate(-50%, -50%);
	pointer-events: none;
}

.kp-ring::before,
.kp-card .kp-cover:not([class*="kp-art--"]) .wp-block-cover__inner-container p::before {
	border-radius: 50%;
	border: 1.5px solid rgba(53, 224, 255, 0.65);
	box-shadow: 0 0 22px rgba(53, 224, 255, 0.28), inset 0 0 18px rgba(53, 224, 255, 0.1);
}

.kp-ring::after,
.kp-card .kp-cover:not([class*="kp-art--"]) .wp-block-cover__inner-container p::after {
	background: radial-gradient(circle 1.6px at 85.36% 14.64%,
		rgba(53, 224, 255, 1) 0 100%, rgba(53, 224, 255, 0) 100%);
	filter: drop-shadow(0 0 5px rgba(53, 224, 255, 0.95))
	        drop-shadow(0 0 12px rgba(53, 224, 255, 0.55));
}

@media (max-width: 600px) {
	.kp-ring::before,
	.kp-ring::after,
	.kp-card .kp-cover:not([class*="kp-art--"]) .wp-block-cover__inner-container p::before,
	.kp-card .kp-cover:not([class*="kp-art--"]) .wp-block-cover__inner-container p::after {
		width: 148%;
	}
}

/* Photon Ring's own neon accents. Scoped to the game, so the studio's
   green-and-gold identity stays the studio's. */
.kp-chip--neon {
	color: #35E0FF;
	border-color: #35E0FF;
}

.kp-neon-rule {
	height: 1px;
	border: 0;
	background: linear-gradient(90deg, rgba(53, 224, 255, 0.6) 0%, rgba(255, 45, 200, 0.6) 100%);
}

/* Placeholder cover art: swap the gradient for a real image any time. */
.kp-cover {
	border-radius: 8px;
	overflow: hidden;
}

.kp-cover .wp-block-cover__inner-container {
	width: 100%;
}

/* -------------------------------------------------------------
   Hero button pair spacing. The seam runs down the exact centre of
   the page, so the two buttons are given a matching minimum width —
   otherwise the longer label drags the pair off-centre and the seam
   crowds the inner edge of the second button instead of splitting
   the gap between them.
   ------------------------------------------------------------- */

.kp-btn-pair {
	column-gap: 2.75rem;
	row-gap: 0.9rem;
}

.kp-btn-pair .wp-block-button__link {
	min-width: 12.5rem;
	text-align: center;
}

@media (max-width: 600px) {
	.kp-btn-pair {
		column-gap: 1rem;
	}

	.kp-btn-pair .wp-block-button__link {
		min-width: 14rem;
	}
}

/* -------------------------------------------------------------
   Hero button pair. The one place the split is spelled out in the
   controls: green on the left, gold on the right, matching the
   headline above it. Fill vs outline keeps the hierarchy readable —
   two filled colours side by side would flatten it.
   ------------------------------------------------------------- */

.kp-btn--kiwi > .wp-block-button__link {
	background-color: var(--wp--preset--color--kiwi);
	color: var(--wp--preset--color--ink);
	border: 1px solid var(--wp--preset--color--kiwi);
}

.kp-btn--kiwi > .wp-block-button__link:hover,
.kp-btn--kiwi > .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--pear);
	border-color: var(--wp--preset--color--pear);
	color: var(--wp--preset--color--ink);
}

.kp-btn--gold-outline > .wp-block-button__link {
	background-color: transparent;
	color: var(--wp--preset--color--pear);
	border: 1px solid var(--wp--preset--color--pear);
}

.kp-btn--gold-outline > .wp-block-button__link:hover,
.kp-btn--gold-outline > .wp-block-button__link:focus {
	background-color: var(--wp--preset--color--pear);
	color: var(--wp--preset--color--ink);
}

/* -------------------------------------------------------------
   Teaser cards for projects that aren't ready to be talked about.
   The sealed variant is deliberately quieter than a real project
   card: hatched instead of lit, so it reads as "not yet" rather
   than as a project with missing information.
   ------------------------------------------------------------- */

.kp-art--sealed {
	background-color: #121016;
	background-image: repeating-linear-gradient(
		135deg,
		rgba(155, 152, 164, 0.07) 0,
		rgba(155, 152, 164, 0.07) 1px,
		transparent 1px,
		transparent 11px
	);
}

.kp-art--teaser {
	background-color: #121016;
	background-image:
		radial-gradient(circle at 30% 40%, rgba(73, 150, 7, 0.16), transparent 55%),
		radial-gradient(circle at 72% 66%, rgba(247, 136, 2, 0.14), transparent 55%);
}

/* Hooked: a line dropped in from above, behind the title. Inline SVG in the
   stylesheet, so there is no extra request and it recolours with a find. */
.kp-art--hook {
	background-color: #121016;
	background-image:
		radial-gradient(circle at 30% 42%, rgba(73, 150, 7, 0.15), transparent 55%),
		radial-gradient(circle at 74% 68%, rgba(247, 136, 2, 0.12), transparent 55%);
	background-repeat: no-repeat;
}

/* The hook hangs off the title, not off the panel. Anchoring it to the text
   keeps it on the final letter at any font size or column width, where a
   background-position percentage is measured against the panel and drifts as
   the centred word changes width.

   It targets the heading itself rather than a wrapper span, so it works on
   markup already saved in the database as well as on markup the pattern
   renders — a rule that needs new markup cannot reach a page that was saved
   before the rule existed.

   Geometry, in em so it scales with the type:
     - the drawing's content starts 10.9% in from its left edge
     - its lowest point sits 87.8% down the box
   The point's tip is 69% down the box and the barb 19.5% across, so at 5em
   tall a top of -2.50em puts the tip just under the baseline and the barb
   under the final letter. The line runs up out of the panel, which the cover
   block clips. */
.kp-art--hook .wp-block-cover__inner-container {
	text-align: center;
}

.kp-art--hook .wp-block-cover__inner-container :where(h1, h2, h3, h4, h5, h6) {
	position: relative;
	display: inline-block;
}

.kp-art--hook .wp-block-cover__inner-container :where(h1, h2, h3, h4, h5, h6)::after {
	content: "";
	position: absolute;
	top: -2.50em;                /* tip clears the baseline, so the point sits
	                                below the letter rather than through it */
	left: calc(100% - 0.60em);   /* half the final letter, plus the barb's own
	                                0.298em offset inside the drawing */
	width: 1.524em;              /* 5em x 64/210 */
	height: 5em;
	background: url("assets/hook.svg") center / contain no-repeat;
	pointer-events: none;
}

/* -------------------------------------------------------------
   5. Status chips — a game is either shipped, in progress, or an idea.
   ------------------------------------------------------------- */

.kp-chip {
	display: inline-block;
	padding: 0.3em 0.7em;
	border: 1px solid currentColor;
	border-radius: 3px;
	font-size: 0.72rem;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	line-height: 1;
	/* Hang the chip left by its own inset so the text inside lines up with the
	   body copy below it. Without this the border box aligns but the words sit
	   about 9px in, which reads as a misalignment. The em matches the padding,
	   so it stays correct if the chip's font size changes. */
	margin-left: calc(-0.7em - 1px);
}

/* Undo the hang where a chip is not sitting above left-aligned text. */
.has-text-align-center > .kp-chip,
.kp-chip.is-not-hung {
	margin-left: 0;
}

/* -------------------------------------------------------------
   6. Content polish
   ------------------------------------------------------------- */

.entry-content > * + * {
	margin-block-start: 1.4rem;
}

.wp-block-post-title a:hover {
	color: #F78802;
}

.kp-rule {
	height: 1px;
	background: linear-gradient(90deg, rgba(73, 150, 7, 0.5) 0%, rgba(247, 136, 2, 0.5) 100%);
	border: 0;
}

/* Query loop grids breathe a little more than core's default. */
.wp-block-post-template.is-layout-grid {
	gap: 1.5rem;
}

/* Stacked lockup (mark + KiwiPear + STUDIOS), used as the footer sign-off.
   Note: this file's contents changed while its name stayed the same, so a
   hard refresh is needed to see an update. */
.kp-lockup {
	width: 148px;
	aspect-ratio: 518 / 568;
	margin-inline: auto;
	background: url("assets/logo-lockup.svg") center / contain no-repeat;
}

@media (max-width: 600px) {
	.kp-lockup { width: 124px; }
}

/* Footer */
.kp-footer {
	border-top: 1px solid #17151a;
}

/* -------------------------------------------------------------
   Fluent Forms, dressed to match the theme.

   The free plugin has no styler, so this does the job in CSS — which is
   better anyway: rebuild or replace the form and it still matches. Every
   selector is prefixed with .fluentform so nothing here leaks into the
   rest of the site, and the two-class specificity beats the plugin's own
   single-class rules without needing !important.
   ------------------------------------------------------------- */

.fluentform .ff-el-group {
	margin-bottom: 1.4rem;
}

.fluentform .ff-el-input--label label {
	font-family: var(--wp--preset--font-family--utility);
	font-size: var(--wp--preset--font-size--tiny);
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.14em;
	color: var(--wp--preset--color--muted);
	margin-bottom: 0.5rem;
}

.fluentform .ff-el-is-required.asterisk-right label::after,
.fluentform .ff-el-is-required.asterisk-left label::before {
	color: var(--wp--preset--color--pear);
}

.fluentform .ff-el-form-control {
	width: 100%;
	background-color: var(--wp--preset--color--rind);
	color: var(--wp--preset--color--flesh);
	border: 1px solid var(--wp--preset--color--seam);
	border-radius: 4px;
	padding: 0.8rem 1rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	line-height: 1.5;
	transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.fluentform .ff-el-form-control::placeholder {
	color: rgba(155, 152, 164, 0.65);
}

.fluentform .ff-el-form-control:focus {
	outline: none;
	border-color: var(--wp--preset--color--kiwi);
	box-shadow: 0 0 0 3px rgba(73, 150, 7, 0.28);
}

.fluentform textarea.ff-el-form-control {
	min-height: 9rem;
	resize: vertical;
}

/* The plugin writes the button colour inline on the element, and an inline
   style outranks any stylesheet rule no matter how specific — so the three
   colour properties need !important. Everything else here is ordinary CSS.
   The alternative is setting the colours per-form in the plugin's button
   styler, but then a new form starts blue again. */
.fluentform .ff-btn-submit,
.fluentform button.ff-btn-submit,
.fluentform .ff_submit_btn_wrapper button {
	background-color: var(--wp--preset--color--pear) !important;
	color: var(--wp--preset--color--ink) !important;
	border: 1px solid var(--wp--preset--color--pear) !important;
	border-radius: 4px;
	padding: 0.85rem 1.5rem;
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	font-weight: 600;
	letter-spacing: 0.01em;
	cursor: pointer;
	box-shadow: none;
	transition: background-color 0.2s ease, border-color 0.2s ease;
}

.fluentform .ff-btn-submit:hover,
.fluentform .ff-btn-submit:focus,
.fluentform button.ff-btn-submit:hover,
.fluentform button.ff-btn-submit:focus,
.fluentform .ff_submit_btn_wrapper button:hover,
.fluentform .ff_submit_btn_wrapper button:focus {
	background-color: var(--wp--preset--color--kiwi) !important;
	border-color: var(--wp--preset--color--kiwi) !important;
	color: var(--wp--preset--color--ink) !important;
}

.fluentform .ff-btn-submit:focus-visible {
	outline: 2px solid var(--wp--preset--color--flesh);
	outline-offset: 3px;
}

/* consent checkbox and any radio/checkbox options */
.fluentform .ff-el-form-check-label,
.fluentform .ff_t_c label {
	font-family: var(--wp--preset--font-family--body);
	font-size: var(--wp--preset--font-size--small);
	color: var(--wp--preset--color--muted);
	text-transform: none;
	letter-spacing: 0;
}

.fluentform input[type="checkbox"],
.fluentform input[type="radio"] {
	accent-color: var(--wp--preset--color--kiwi);
}

/* validation and confirmation */
.fluentform .ff-el-is-error .ff-el-form-control {
	border-color: #E5484D;
}

.fluentform .error,
.fluentform .text-danger {
	font-family: var(--wp--preset--font-family--utility);
	font-size: var(--wp--preset--font-size--tiny);
	color: #E5484D;
}

.fluentform .ff-message-success {
	background-color: rgba(73, 150, 7, 0.12);
	border: 1px solid var(--wp--preset--color--kiwi);
	border-radius: 6px;
	color: var(--wp--preset--color--flesh);
	padding: 1rem 1.2rem;
}

/* -------------------------------------------------------------
   7. Responsive + accessibility floor
   ------------------------------------------------------------- */

@media (max-width: 781px) {
	.kp-seam::before {
		opacity: 0.5;
	}
}

@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	.kp-card,
	.kp-card::before,
	.kp-card::after {
		transition: none;
	}

	.kp-card:hover,
	.kp-card:focus-within {
		transform: none;
	}

	.kp-card::before,
	.kp-card::after {
		transform: scaleY(1);
	}
}

.screen-reader-text {
	border: 0;
	clip-path: inset(50%);
	height: 1px;
	margin: -1px;
	overflow: hidden;
	padding: 0;
	position: absolute;
	width: 1px;
	word-wrap: normal !important;
}
