/*!
Theme Name: NutterJuck
Theme URI: https://nutterjuck.com.au/
Author: The Service Edit
Author URI: https://theserviceedit.com
Description: Custom WooCommerce theme for NutterJuck Lures. Handmade timber fishing lures, built in Australia. No page builders, no framework, no jQuery on the storefront.
Version: 1.0.0
Requires at least: 6.4
Tested up to: 6.8
Requires PHP: 8.1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Text Domain: nutterjuck
Tags: e-commerce, custom-menu, featured-images, translation-ready, accessibility-ready
WC requires at least: 8.0
WC tested up to: 9.9
*/

/* ==========================================================================
   NUTTERJUCK — CORE DESIGN SYSTEM
   Loaded on every page. Page-specific rules live in assets/css/.

   Contents
   01. Fonts
   02. Tokens
   03. Reset + document
   04. Accessibility utilities
   05. Site header
   06. Page heading
   07. Button system
   08. Form fields
   09. Site footer
   10. WordPress core classes
   11. Responsive + motion
   ========================================================================== */


/* 01. Fonts ================================================================
   Self-hosted. Replaces the render-blocking Google Fonts request and the two
   preconnects. Rendering is identical; the network waterfall is one hop
   shorter and no third party sees the visitor's IP.
   ========================================================================== */

@font-face {
	font-family: 'Anton';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('assets/fonts/anton-latin-400.woff2') format('woff2');
	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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Archivo';
	font-style: normal;
	font-weight: 400;
	font-display: swap;
	src: url('assets/fonts/archivo-latin-400.woff2') format('woff2');
	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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Archivo';
	font-style: normal;
	font-weight: 500;
	font-display: swap;
	src: url('assets/fonts/archivo-latin-500.woff2') format('woff2');
	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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
	font-family: 'Archivo';
	font-style: normal;
	font-weight: 600;
	font-display: swap;
	src: url('assets/fonts/archivo-latin-600.woff2') format('woff2');
	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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


/* 02. Tokens ===============================================================
   Ink on paper. The splash page inverts these two values and nothing else —
   see assets/css/splash.css. Every border, rule and hover fill in the theme
   resolves from this pair, which is why the inversion costs two lines.
   ========================================================================== */

:root {
	--ink: #000;
	--paper: #fff;

	/* Derived from the source. Hairlines were written as rgba(0,0,0,.14)
	   throughout; expressed as a token so the splash inversion carries. */
	--hairline: rgba(0, 0, 0, .14);

	/* The single border weight used across the whole site. */
	--rule: 1.5px;
}


/* 03. Reset + document =====================================================
   ========================================================================== */

*,
*::before,
*::after {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

body {
	background: var(--paper);
	color: var(--ink);
	font-family: 'Archivo', sans-serif;
	-webkit-font-smoothing: antialiased;
	min-height: 100dvh;
	display: flex;
	flex-direction: column;
}

main {
	flex: 1;
}

/* Images never overflow their column. The source relied on every image being
   explicitly sized; WordPress-uploaded media is not, so this is load-bearing
   for editor-inserted content. It cannot change the existing layout because
   no existing image exceeds its container. */
img {
	max-width: 100%;
	height: auto;
}

a {
	color: inherit;
}


/* 04. Accessibility utilities ==============================================
   The skip link and .screen-reader-text are visually hidden until focused,
   so they add nothing to the rendered design.
   ========================================================================== */

.screen-reader-text {
	position: absolute !important;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

.skip-link {
	position: absolute;
	top: -100px;
	left: 0;
	z-index: 100;
	font-family: 'Anton', sans-serif;
	font-size: .8rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--paper);
	background: var(--ink);
	border: var(--rule) solid var(--ink);
	padding: .85rem 1.4rem;
	transition: top .2s ease;
}

.skip-link:focus {
	top: 0;
}

/* Baseline keyboard focus. The source declared :focus-visible on three
   buttons only; interactive text links, the cart button and every form field
   had no visible focus state, which fails WCAG 2.1 AA (2.4.7). This is the
   one deliberate addition to the visual design — it is invisible to mouse
   and touch users and appears only on keyboard navigation. */
:focus-visible {
	outline: 2px solid var(--ink);
	outline-offset: 3px;
}


/* 05. Site header ==========================================================
   Identical across the shop, contact and every product page in the source.
   Declared once here.
   ========================================================================== */

.site-header {
	position: sticky;
	top: 0;
	background: var(--paper);
	border-bottom: var(--rule) solid var(--ink);
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 1rem clamp(1.2rem, 4vw, 2.6rem);
	z-index: 10;
}

.wordmark {
	font-family: 'Anton', sans-serif;
	font-size: 1.05rem;
	letter-spacing: .04em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--ink);
	display: flex;
	align-items: center;
	gap: .6rem;
}

.wordmark img {
	height: 26px;
	width: auto;
	display: block;
}

.nav {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 3vw, 2rem);
}

/* Menu items. In the source these were hand-written <a class="back"> links;
   they now come from a WordPress menu, so the class is applied to the
   generated <a> and the list chrome is stripped. */
.nav ul {
	display: flex;
	align-items: center;
	gap: clamp(1rem, 3vw, 2rem);
	list-style: none;
}

.back {
	font-size: .7rem;
	letter-spacing: .28em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--ink);
	border-bottom: var(--rule) solid transparent;
	padding-bottom: 2px;
	transition: border-color .3s ease;
	display: inline-block;
}

.back:hover,
.nav li.current-menu-item > .back {
	border-color: var(--ink);
}

.cart {
	font-family: 'Archivo', sans-serif;
	font-size: .7rem;
	letter-spacing: .28em;
	text-transform: uppercase;
	color: var(--ink);
	background: none;
	border: var(--rule) solid var(--ink);
	padding: .55rem .9rem;
	cursor: pointer;
	transition: background .3s ease, color .3s ease;
}

.cart:hover {
	background: var(--ink);
	color: var(--paper);
}


/* 06. Page heading =========================================================
   The oversized Anton page title used on the shop, contact and every
   WordPress page. Bottom padding differs on the shop archive only.
   ========================================================================== */

.head {
	text-align: center;
	padding: clamp(3rem, 8vw, 5.5rem) 1.5rem clamp(1rem, 3vw, 2rem);
}

.head--shop {
	padding-bottom: clamp(1.5rem, 4vw, 2.5rem);
}

.head h1 {
	font-family: 'Anton', sans-serif;
	font-size: clamp(2.6rem, 11vw, 6rem);
	line-height: .92;
	letter-spacing: .01em;
	text-transform: uppercase;
}

.head p {
	margin-top: 1.1rem;
	font-size: .74rem;
	letter-spacing: .4em;
	text-transform: uppercase;
}

/* The small uppercase label used above headings and beside spec groups. */
.eyebrow {
	font-size: .68rem;
	letter-spacing: .3em;
	text-transform: uppercase;
	opacity: .55;
}


/* 07. Button system ========================================================
   One mechanism, four sizes. The source repeated this fill-from-below
   treatment as .view, .btn, .buy and .contact button with identical
   internals and different padding. Merged; computed output unchanged.
   ========================================================================== */

.nj-btn {
	font-family: 'Anton', sans-serif;
	letter-spacing: .12em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--paper);
	background: var(--ink);
	border: var(--rule) solid var(--ink);
	cursor: pointer;
	position: relative;
	overflow: hidden;
	z-index: 0;
	transition: color .4s ease;
}

.nj-btn::before {
	content: "";
	position: absolute;
	inset: 0;
	background: var(--paper);
	transform: translateY(101%);
	transition: transform .4s cubic-bezier(.7, 0, .2, 1);
	z-index: -1;
}

.nj-btn:hover {
	color: var(--ink);
}

.nj-btn:hover::before {
	transform: translateY(0);
}

/* Card action — "View the lure" on the shop grid. */
.nj-btn--view {
	margin-top: .2rem;
	font-size: .86rem;
	padding: .85rem 1.1rem;
	text-align: center;
}

/* Band action — "Find them on Instagram". */
.nj-btn--band {
	margin-top: .6rem;
	font-size: .86rem;
	padding: .9rem 1.4rem;
}

/* Form action — contact form submit. */
.nj-btn--form {
	font-size: .86rem;
	padding: .95rem 1.1rem;
}

/* Buy action — add to cart on the product page. */
.nj-btn--buy {
	align-self: flex-start;
	margin-top: .4rem;
	font-size: .95rem;
	padding: 1rem 2.2rem;
}

/* Sold out / unavailable. Ported from the runtime CSS in stock.js so a
   sold-out button looks the same as it does on the live site today. */
.nj-btn[disabled],
.nj-btn[aria-disabled="true"] {
	opacity: .4;
	cursor: not-allowed;
}

.nj-btn[disabled]:hover,
.nj-btn[aria-disabled="true"]:hover {
	color: var(--paper);
}

.nj-btn[disabled]:hover::before,
.nj-btn[aria-disabled="true"]:hover::before {
	transform: translateY(101%);
}


/* 08. Form fields ==========================================================
   Shared by the contact form, the email capture band, checkout, and the
   account screens. One definition, so a field added later cannot drift.
   ========================================================================== */

.nj-field {
	width: 100%;
	border: var(--rule) solid var(--ink);
	background: var(--paper);
	color: var(--ink);
	font-family: 'Archivo', sans-serif;
	font-size: .9rem;
	letter-spacing: .02em;
	padding: .85rem 1rem;
}

.nj-field::placeholder {
	color: var(--ink);
	opacity: .45;
}

.nj-field:focus {
	outline: none;
}

.nj-field:focus-visible {
	outline: 2px solid var(--ink);
	outline-offset: -4px;
}

textarea.nj-field {
	resize: vertical;
	min-height: 150px;
}

/* Inline email capture — input and button share one border box. */
.signup {
	display: flex;
	width: min(100%, 440px);
	border: var(--rule) solid var(--ink);
	margin-top: .4rem;
}

.signup input {
	flex: 1;
	min-width: 0;
	border: none;
	background: var(--paper);
	color: var(--ink);
	font-family: 'Archivo', sans-serif;
	font-size: .9rem;
	letter-spacing: .02em;
	padding: .95rem 1rem;
}

.signup input::placeholder {
	color: var(--ink);
	opacity: .45;
}

.signup input:focus {
	outline: none;
}

.signup input:focus-visible {
	outline: 2px solid var(--ink);
	outline-offset: -4px;
}

.signup button {
	font-family: 'Anton', sans-serif;
	font-size: .82rem;
	letter-spacing: .12em;
	text-transform: uppercase;
	color: var(--paper);
	background: var(--ink);
	border: none;
	border-left: var(--rule) solid var(--ink);
	padding: 0 1.4rem;
	cursor: pointer;
	transition: opacity .3s ease;
}

.signup button:hover {
	opacity: .85;
}

.signup-note {
	font-size: .66rem;
	letter-spacing: .24em;
	text-transform: uppercase;
	opacity: .5;
}

/* Success replacements for both forms. */
.signup-done {
	font-family: 'Anton', sans-serif;
	font-size: 1.1rem;
	letter-spacing: .06em;
	text-transform: uppercase;
	margin-top: .4rem;
}

.done {
	font-family: 'Anton', sans-serif;
	font-size: 1.2rem;
	letter-spacing: .06em;
	text-transform: uppercase;
	margin-top: .4rem;
}

/* Validation message. Not present in the source — the forms posted to a
   third party and never rendered an error inline. Required now that
   submissions are validated server-side. */
.nj-form-error {
	font-size: .7rem;
	letter-spacing: .18em;
	text-transform: uppercase;
	font-weight: 600;
	border-left: 3px solid var(--ink);
	padding-left: 1rem;
}


/* 09. Site footer ==========================================================
   ========================================================================== */

.site-footer {
	border-top: var(--rule) solid var(--ink);
	text-align: center;
	padding: 2.2rem 1.5rem;
	font-size: .68rem;
	letter-spacing: .3em;
	text-transform: uppercase;
}

.site-footer a {
	color: var(--ink);
}

/* Policy links. Sized between the footer line and the credit so the hierarchy
   reads footer text → policies → credit. */
.footer-nav {
	margin-top: 1rem;
}

.footer-nav__list {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: .6rem 1.6rem;
}

.footer-nav__list a {
	font-size: .62rem;
	letter-spacing: .26em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--ink);
	opacity: .7;
	border-bottom: 1px solid transparent;
	padding-bottom: 1px;
	transition: opacity .3s ease, border-color .3s ease;
}

.footer-nav__list a:hover {
	opacity: 1;
	border-color: var(--ink);
}

.credit {
	display: block;
	margin-top: 1rem;
	font-size: .6rem;
	letter-spacing: .28em;
	opacity: .55;
}

.credit a {
	text-decoration: none;
	border-bottom: 1px solid transparent;
	padding-bottom: 1px;
	transition: border-color .3s ease;
}

.credit a:hover {
	border-color: var(--ink);
}


/* 09b. Page and post content ===============================================
   Used by pages, posts, search results and the contact page. The contact
   layout is lifted directly from the source; the rest inherits the same
   typographic scale so editor-written content cannot look foreign.
   ========================================================================== */

.nj-shell {
	width: min(100%, 1100px);
	margin: 0 auto;
	padding: 0 clamp(1.2rem, 4vw, 2.6rem);
}

.nj-shell--narrow {
	width: min(100%, 620px);
}

.nj-page {
	padding-bottom: clamp(3.5rem, 9vw, 6rem);
	font-size: .95rem;
	line-height: 1.7;
	letter-spacing: .02em;
}

.nj-page > p,
.nj-page > ul,
.nj-page > ol,
.nj-page > blockquote,
.nj-page > figure,
.nj-page > table {
	margin-bottom: 1.2rem;
}

.nj-page h2,
.nj-page h3,
.nj-page h4 {
	font-family: 'Anton', sans-serif;
	letter-spacing: .02em;
	text-transform: uppercase;
	line-height: 1.05;
	margin: 2rem 0 .8rem;
}

.nj-page h2 {
	font-size: clamp(1.4rem, 4vw, 1.9rem);
}

.nj-page h3 {
	font-size: 1.15rem;
}

.nj-page h4 {
	font-size: 1rem;
}

.nj-page ul,
.nj-page ol {
	padding-left: 1.3rem;
}

.nj-page li {
	margin-bottom: .4rem;
}

.nj-page blockquote {
	border-left: 3px solid var(--ink);
	padding-left: 1rem;
	max-width: 46ch;
}

.nj-page a {
	color: var(--ink);
	text-decoration: none;
	border-bottom: 1px solid var(--ink);
	padding-bottom: 1px;
}

.nj-featured {
	margin-bottom: 1.6rem;
	border: var(--rule) solid var(--ink);
	background: #000;
}

.nj-featured img {
	display: block;
	width: 100%;
	height: auto;
}

/* ---- Contact page ---- */

.contact-wrap {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1.2rem;
	padding: clamp(1rem, 3vw, 2rem) 0 clamp(3.5rem, 9vw, 6rem);
	text-align: center;
}

.contact-wrap p.lead {
	max-width: 46ch;
	font-size: .9rem;
	line-height: 1.6;
	letter-spacing: .02em;
}

.contact {
	display: flex;
	flex-direction: column;
	gap: .8rem;
	width: min(100%, 480px);
	margin-top: .4rem;
	text-align: left;
}

/* Social profiles below the form. Deliberately the quietest thing on the
   page: the form is the conversion, these are the consolation prize. The
   type is the .back / .side-menu__social treatment already used in the
   header and the side menu, so no new vocabulary is introduced. */
.contact-social {
	width: min(100%, 480px);
	margin-top: 2.4rem;
	padding-top: 1.6rem;
	border-top: 1px solid var(--hairline);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1rem;
}

.contact-social__label {
	font-size: .62rem;
	letter-spacing: .28em;
	text-transform: uppercase;
	opacity: .55;
}

.contact-social__list {
	display: flex;
	align-items: baseline;
	justify-content: center;
	gap: clamp(1.4rem, 5vw, 2.4rem);
	list-style: none;
}

.contact-social__list a {
	font-size: .7rem;
	letter-spacing: .28em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--ink);
	border-bottom: var(--rule) solid transparent;
	padding-bottom: 2px;
	display: inline-block;
	transition: border-color .3s ease;
}

.contact-social__list a:hover,
.contact-social__list a:focus-visible {
	border-color: var(--ink);
}

/* ---- List entries ---- */

.nj-entry {
	border-bottom: 1px solid var(--hairline);
	padding-bottom: 1.6rem;
	margin-bottom: 1.6rem;
	display: flex;
	flex-direction: column;
	gap: .4rem;
}

.nj-entry:last-child {
	border-bottom: none;
}

.nj-entry__title {
	font-family: 'Anton', sans-serif;
	font-size: 1.35rem;
	letter-spacing: .03em;
	text-transform: uppercase;
	line-height: 1.05;
}

.nj-entry__title a {
	text-decoration: none;
	color: var(--ink);
	border: none;
}

.nj-entry__date {
	font-size: .66rem;
	letter-spacing: .28em;
	text-transform: uppercase;
	opacity: .55;
}

.nj-entry__excerpt {
	font-size: .88rem;
	line-height: 1.6;
}

.nj-entry__more {
	align-self: flex-start;
	font-size: .66rem;
	letter-spacing: .24em;
	text-transform: uppercase;
	text-decoration: none;
	color: var(--ink);
	border-bottom: var(--rule) solid var(--ink);
	padding-bottom: 2px;
	margin-top: .3rem;
}

/* ---- Pagination ---- */

.nj-pagination {
	display: flex;
	gap: .5rem;
	justify-content: center;
	margin-top: 2rem;
	flex-wrap: wrap;
}

.nj-pagination a,
.nj-pagination span {
	display: grid;
	place-items: center;
	min-width: 2.4rem;
	height: 2.4rem;
	padding: 0 .6rem;
	border: var(--rule) solid var(--ink);
	font-size: .72rem;
	letter-spacing: .12em;
	text-decoration: none;
	color: var(--ink);
	transition: background .25s ease, color .25s ease;
}

.nj-pagination a:hover,
.nj-pagination .current {
	background: var(--ink);
	color: var(--paper);
}

/* ---- Sale prices, wherever a price is rendered ---- */

.price del,
.nj-entry__date del {
	opacity: .45;
	margin-right: .4rem;
}

.price ins,
.nj-entry__date ins {
	text-decoration: none;
}


/* 09c. Bands and empty states ==============================================
   Shared layout used by the shop bands, the 404 page, search results and any
   empty listing. Lived in shop.css originally, which meant the 404 page
   rendered them unstyled — the button collided with the paragraph.
   ========================================================================== */

/* Full-width bands below the grid. */
.band {
	border-top: var(--rule) solid var(--ink);
	text-align: center;
	padding: clamp(3rem, 7vw, 5rem) 1.5rem;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1.2rem;
}

.band h2 {
	font-family: 'Anton', sans-serif;
	font-size: clamp(1.8rem, 6vw, 3rem);
	letter-spacing: .02em;
	text-transform: uppercase;
	line-height: .95;
}

.band p {
	max-width: 48ch;
	font-size: .9rem;
	line-height: 1.6;
	letter-spacing: .02em;
}

/* Empty catalogue. Not present in the source, because the source could not
   have an empty catalogue. */
.shop-empty {
	text-align: center;
	padding: clamp(3rem, 8vw, 6rem) 1.5rem;
	font-size: .74rem;
	letter-spacing: .4em;
	text-transform: uppercase;
}


/* 10. WordPress core classes ===============================================
   Required for theme completeness. None of these appear in the current
   design; they exist so editor-inserted content in a future blog post or
   page renders correctly instead of unstyled.
   ========================================================================== */

.alignleft {
	float: left;
	margin-right: 1.5rem;
	margin-bottom: 1rem;
}

.alignright {
	float: right;
	margin-left: 1.5rem;
	margin-bottom: 1rem;
}

.aligncenter {
	display: block;
	margin-left: auto;
	margin-right: auto;
	margin-bottom: 1rem;
}

.alignwide,
.alignfull {
	max-width: 100%;
}

.wp-caption {
	max-width: 100%;
}

.wp-caption-text,
.gallery-caption {
	font-size: .7rem;
	letter-spacing: .18em;
	text-transform: uppercase;
	opacity: .55;
	margin-top: .6rem;
	text-align: center;
}

.clearfix::after {
	content: "";
	display: table;
	clear: both;
}


/* 11. Responsive + motion ==================================================
   ========================================================================== */

@media (max-width: 560px) {
	.wordmark span {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	* {
		transition: none !important;
	}
}

/* ==========================================================================
   ADMIN BAR OFFSET
   Only affects logged-in administrators. WordPress pushes the page down 32px
   for the admin bar, but fixed-position elements ignore that, so the menu
   button and both slide-out panels sat underneath it.
   ========================================================================== */

body.admin-bar .menu-toggle {
	top: calc(clamp(20px, 3vw, 34px) + 32px);
}

body.admin-bar .side-menu__panel,
body.admin-bar .nj-drawer__panel {
	top: 32px;
}

@media screen and (max-width: 782px) {
	body.admin-bar .menu-toggle {
		top: calc(clamp(20px, 3vw, 34px) + 46px);
	}

	body.admin-bar .side-menu__panel,
	body.admin-bar .nj-drawer__panel {
		top: 46px;
	}
}
