/*
Theme Name:   Hansdotter
Theme URI:    https://hansdotter.nofont.design
Author:       nofont
Author URI:   https://nofont.com
Description:  Block child theme for Hansdotter — a tufting studio in Linköping.
              Colour presets live in theme.json; everything below is CSS that
              theme.json cannot express.
Template:     twentytwentyfive
Version:      0.3.0
Requires at least: 6.7
Tested up to: 7.0
Requires PHP: 8.0
License:      GPL-2.0-or-later
License URI:  https://www.gnu.org/licenses/gpl-2.0.html
Text Domain:  hansdotter
*/

/* ==========================================================================
   Ported from Site Editor → Global Styles → Additional CSS (2026-08-02).
   That CSS was stored against the *twentytwentyfive* theme and would have
   silently stopped applying the moment this child theme was activated —
   global styles are per-theme. Living here, it is version controlled,
   reviewable and deploys with the theme.
   ========================================================================== */

/* --- Buttons -------------------------------------------------------------- */
.wp-block-button__link {
	transition: all 0.3s ease;
}

/* The hover colour is the same token the button now uses at rest, so this is
   only the scale plus a darkening. It used to be the hex #727F78 written out by
   hand, which happened to match custom-r-nder-logga and would have stopped
   matching the moment the palette moved. */
.wp-block-button__link:hover {
	background-color: var(--wp--preset--color--custom-r-nder-logga, #727F78) !important;
	transform: scale(1.08);
}

/* ...except on the blob buttons, which must never paint their own background.
   The rule above is site-wide and carries !important, inherited from the
   original design when buttons were plain rectangles. The blob buttons are
   transparent with the colour on a masked ::before, so letting that rule
   through paints an UNMASKED rectangle over the drawing on hover — the blob
   vanishes and a hard green box appears. !important here is answering
   !important, not laziness. */
.post-type-archive-product .button:hover,
.post-type-archive-product .add_to_cart_button:hover,
.post-type-archive-product .product_type_simple:hover,
.post-type-archive-product .product_type_variable:hover,
.single-product .single_add_to_cart_button:hover {
	background-color: transparent !important;
}

/* --- Kurser image hover --------------------------------------------------- */
img[src*="kurser.png"] {
	transition: transform 0.3s ease;
}

img[src*="kurser.png"]:hover {
	transform: scale(1.1); /* 10 % större */
}

footer {
	/* spacing-60 is clamp(30px, 7vw, 70px): about 60px on a laptop, and it
	   collapses on narrow screens instead of holding a fixed gap there. */
	margin-top: var(--wp--preset--spacing--60);
}

/* --- WooCommerce arkivsida ------------------------------------------------
   The "BOKA" buttons: an SVG mask over a solid fill, with the original button
   text hidden and replaced via ::after.

   Typeface: Saira Condensed, replacing Norwester. Norwester ships only 109
   glyphs — it has Ö but not Å, Ä, å, ä or ö, so "BESTÄLL" was already falling
   back mid-word. Saira Condensed matches its squared construction and cap
   height to within 2%, and covers Swedish completely.

   The mask lives in the theme, not the media library. It used to be loaded from
   an absolute production URL, which meant local and staging silently rendered
   unmasked rectangles — and the buttons would have broken outright on any
   domain change. Relative URLs in this file resolve against the theme folder,
   so it now works in every environment and is version controlled with the CSS
   that depends on it.
   -------------------------------------------------------------------------- */
.post-type-archive-product .button,
.post-type-archive-product .add_to_cart_button,
.post-type-archive-product .product_type_simple,
.post-type-archive-product .product_type_variable,
.single-product .single_add_to_cart_button {
	/* No background here — the blob is painted by ::before, so the mask can
	   never touch the label. */
	background: transparent;
	position: relative;
	isolation: isolate;
	color: #fff !important;

	display: flex;
	align-items: center;
	justify-content: center;

	font-family: var(--wp--preset--font-family--saira-condensed, "Saira Condensed", sans-serif);

	/* !important is load-bearing here, not laziness. The button carries
	   WordPress's has-small-font-size preset class, which WordPress itself
	   emits with !important — so any plain declaration loses no matter how
	   specific. This is the one place that has to fight back. */
	font-size: 24px !important;

	font-weight: 600;
	letter-spacing: 2px;
	text-transform: uppercase;
	text-decoration: none;

	border: none;
	border-radius: 0;
	overflow: hidden;

	transition: all .3s ease;

	border-radius: 0;
}

/* --- Blobformen -----------------------------------------------------------
   Hand-drawn in Figma by Andreas, exported to assets/img/blobs/ and used as
   masks. Four shapes cycle across the product grid so neighbouring buttons
   differ; the product page uses a wider drawing of its own.

   Two things about how they are applied:

   The mask is on ::before, NOT on the button. Masking the button clips its
   text — which is why the first version of this worked for "BOKA" and cut the
   descenders off "LÄGG TILL I VARUKORG". Masking a layer behind the text lets
   the shape be as irregular as it likes while the label is never involved.

   mask-size is 100% 100%, and the files carry preserveAspectRatio="none" (added
   by bin/prepare-blobs.sh, because Figma does not write it). Without both, the
   drawing keeps its own proportions and floats letterboxed in the middle of a
   wider button.

   Colour is not baked into the SVG fill, so hover stays a background-color
   change on ::before and the palette lives in one place.
   -------------------------------------------------------------------------- */
:root {
	--hd-blob-1: url("./assets/img/blobs/button_1.svg");
	--hd-blob-2: url("./assets/img/blobs/button_2.svg");
	--hd-blob-3: url("./assets/img/blobs/button_3.svg");
	--hd-blob-4: url("./assets/img/blobs/button_4.svg");
	--hd-blob-wide: url("./assets/img/blobs/button_wide_1.svg");
}




.post-type-archive-product .button::before,
.post-type-archive-product .add_to_cart_button::before,
.post-type-archive-product .product_type_simple::before,
.post-type-archive-product .product_type_variable::before,
.single-product .single_add_to_cart_button::before {
	content: "";
	position: absolute;
	inset: 0;
	z-index: -1;
	background-color: var(--wp--preset--color--custom-loggan, #C2D1CC);
	transition: background-color .3s ease;

	-webkit-mask: var( --hd-blob, var( --hd-blob-1 ) ) center / 100% 100% no-repeat;
	mask: var( --hd-blob, var( --hd-blob-1 ) ) center / 100% 100% no-repeat;
}

/* Assigned by position, not at random: a shape that changed on every page load
   would read as a rendering fault rather than as charm. */
li.wc-block-product:nth-child(4n + 1) .wp-block-button__link { --hd-blob: var( --hd-blob-1 ); }
li.wc-block-product:nth-child(4n + 2) .wp-block-button__link { --hd-blob: var( --hd-blob-2 ); }
li.wc-block-product:nth-child(4n + 3) .wp-block-button__link { --hd-blob: var( --hd-blob-3 ); }
li.wc-block-product:nth-child(4n + 4) .wp-block-button__link { --hd-blob: var( --hd-blob-4 ); }

/* The product page gets the wide drawing. Its label is the longest on the site
   ("LÄGG TILL I VARUKORG"), so the button is roughly 2.5:1 — stretching one of
   the 1.6:1 shapes to fill it would flatten the drawn curves noticeably. The
   wide one is authored at about 3:1 and barely distorts. */
.single-product .single_add_to_cart_button { --hd-blob: var( --hd-blob-wide ); }

/* Sizing needs its own, more specific selector.
   WooCommerce sets width:auto via
     .wp-block-button.wc-block-components-product-button .wp-block-button__link
   — three classes, so it outranks the two-class rule above and the intended
   180px never applied. The button rendered at 55px, shrink-wrapped to the word,
   which is why the blob looked cramped. Matching WooCommerce's own structure
   with one extra class wins on specificity, so no !important is needed.

   min-width rather than width, and padding rather than a fixed height, so the
   padding genuinely participates: a longer label grows the button instead of
   being clipped. A fixed height plus 40px of vertical padding would leave a
   15px content box and crop the text. */
.post-type-archive-product .wp-block-button.wc-block-components-product-button .wp-block-button__link {
	min-width: 180px;
	min-height: 95px;
	height: auto;
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--50);
}

/* On a phone the grid is one column, so a 180×95 blob is a slab across most of
   the screen width and pushes the next course below the fold. The label is four
   letters; it does not need that much room.

   600px is the breakpoint WordPress itself treats as mobile, so this changes
   with the same layout shift rather than at a width of our own choosing.

   The selector repeats the desktop one exactly, so it wins on source order
   alone — no added specificity to unpick later. */
@media (max-width: 600px) {
	.post-type-archive-product .wp-block-button.wc-block-components-product-button .wp-block-button__link {
		min-width: 120px;
		min-height: 65px;

		/* The vertical padding has to come down with it, or min-height never
		   binds: 20px top and bottom around a 34px line box is 74px on its own,
		   and the button ignores the 65px it was given. At 10px the content box
		   is 54px, so min-height is what decides and the button is 65px. */
		padding: var(--wp--preset--spacing--20) var(--wp--preset--spacing--40);
	}
}

/* The label itself is set in PHP — see mu-plugins/boka-button-text.php.
   There used to be a font-size:0 rule here with the word painted back in via
   ::after. It never worked (see above), and screen readers only ever heard
   the original "Add to cart". Renaming the button is simpler and honest. */

/* Hover */
.post-type-archive-product .button:hover,
.post-type-archive-product .add_to_cart_button:hover,
.post-type-archive-product .product_type_simple:hover,
.post-type-archive-product .product_type_variable:hover,
.single-product .single_add_to_cart_button:hover:not(:disabled) {
	transform: scale(1.08);
}

.post-type-archive-product .button:hover::before,
.post-type-archive-product .add_to_cart_button:hover::before,
.post-type-archive-product .product_type_simple:hover::before,
.post-type-archive-product .product_type_variable:hover::before,
.single-product .single_add_to_cart_button:hover:not(:disabled)::before {
	background-color: var(--wp--preset--color--custom-r-nder-logga, #727F78);
}

/* ==========================================================================
   New in this theme
   ========================================================================== */

/* Map embed on HITTA HIT — replaces the 49 MB wp-google-maps plugin.
   The iframe carries its own inline sizing so it stays responsive even while
   this theme is inactive; once hansdotter is live that inline style can come
   off and these rules take over. */
.hansdotter-map {
	margin: var(--wp--preset--spacing--40) 0;
}

.hansdotter-map figcaption {
	margin-top: var(--wp--preset--spacing--20);
	font-size: var(--wp--preset--font-size--small);
	text-align: center;
}


/* --- Produktsidan ---------------------------------------------------------
   The archive had hand-drawn BOKA blobs while the page where you actually book
   showed WooCommerce's default grey rectangle. The blob rules above now cover
   both; this only supplies the size, because the single-product button is a
   plain <button> rather than the block-editor structure the archive uses.
   -------------------------------------------------------------------------- */
.single-product .single_add_to_cart_button {
	min-width: 220px;
	min-height: 90px;
	height: auto;
	padding: var(--wp--preset--spacing--30) var(--wp--preset--spacing--50);
	cursor: pointer;
}

/* Same colour as the archive buttons in every state.
   Before a date is chosen WooCommerce adds a `disabled` class and dims the
   button to opacity .5 via `.woocommerce a.button.disabled`. On the cream
   background that reads as a paler GREEN rather than as a dimmed button, so the
   product page looked like it used a different palette from the listing. The
   selectors below carry an extra element to outrank WooCommerce's three
   classes plus element.

   The pointer still says not-allowed, and WooCommerce still refuses the click
   with its own message, so the state is signalled without changing the colour. */
.single-product .woocommerce button.single_add_to_cart_button.disabled,
.single-product .woocommerce button.single_add_to_cart_button:disabled,
.single-product button.single_add_to_cart_button.disabled,
.single-product button.single_add_to_cart_button:disabled {
	opacity: 1;
	cursor: not-allowed;
}

/* --- Bokningsformuläret ---------------------------------------------------
   WooCommerce lays the variation picker out as a TABLE: the attribute name in a
   th on the left, the control in a td beside it. That puts "Datum" in a narrow
   column next to a list that wants the full width, and it pins the label to the
   vertical middle of whatever sits next to it.

   Everything here is turned into blocks so the form reads as one column:
   label, then dates, then "Antal platser", then the button. Nothing is
   reordered or moved in the markup — the source order was already right, it was
   the table that was arranging it sideways.
   -------------------------------------------------------------------------- */
.single-product form.cart table.variations,
.single-product form.cart table.variations tbody,
.single-product form.cart table.variations tr,
.single-product form.cart table.variations th,
.single-product form.cart table.variations td {
	display: block;
	width: 100%;
	padding: 0;
	margin: 0;
	border: 0;
}

.single-product form.cart table.variations th.label {
	margin-bottom: .5rem;
}

.single-product form.cart table.variations th.label label {
	font-weight: 600;
}

/* Quantity: its own labelled block above the button, not sitting beside it.
   The label is WooCommerce's own, unhidden and renamed to "Antal platser" in
   mu-plugins/boka-button-text.php, so the input keeps exactly one label. */
.single-product form.cart .woocommerce-variation-add-to-cart {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 1rem;
}

.single-product form.cart .quantity {
	display: flex;
	flex-direction: column;
	gap: .5rem;
	margin: 0;
	float: none;
}

/* .screen-reader-text is declared `position: absolute !important` — by core and
   by two other stylesheets — so unhiding it takes !important back. Without it
   the label stays out of flow and prints exactly on top of the input: both
   render at the same coordinates, one over the other. */
.single-product form.cart .quantity label {
	position: static !important;
	width: auto !important;
	height: auto !important;
	margin: 0 !important;
	padding: 0 !important;
	overflow: visible !important;
	clip: auto !important;
	clip-path: none !important;
	white-space: normal !important;
	font-weight: 600;
}

.single-product form.cart .quantity input.qty {
	width: 72px;
	height: 48px;
	padding: 0 .25rem 0 .6rem;
	border: 1px solid var(--wp--preset--color--custom-loggan, #c2d1cc);
	border-radius: 6px;
	text-align: left;
}

/* --- Datumlistan ----------------------------------------------------------
   Replaces the "Datum" dropdown on course pages — see
   mu-plugins/variation-date-list.php.

   The <select> is still in the DOM and still does the work; WooCommerce reads
   and writes it to update price, stock and the button. Hiding it with
   display:none rather than removing it is the whole reason this stays simple.
   -------------------------------------------------------------------------- */
/* Specificity has to match WooCommerce's own
     .woocommerce div.product form.cart .variations select { display: inline-block }
   which is four classes deep. A plain `.hansdotter-dates ~ select` loses to it
   and the dropdown stays on screen underneath the list — visibly, so at least
   this one fails loudly. */
.woocommerce div.product form.cart .variations .hansdotter-dates ~ select {
	display: none;
}

/* The dates make the row tall; without this the "Datum" label floats to the
   vertical middle of the list, level with nothing in particular. */
.woocommerce div.product form.cart .variations th.label,
.woocommerce div.product form.cart .variations td.label {
	vertical-align: top;
	padding-top: 1.1rem;
}

.hansdotter-dates {
	display: flex;
	flex-direction: column;
	gap: .5rem;
	margin-bottom: .75rem;
}

.hansdotter-date {
	display: flex;
	align-items: center;
	gap: .75rem;
	padding: .85rem 1rem;
	border: 1px solid var(--wp--preset--color--custom-loggan, #c2d1cc);
	border-radius: 6px;
	cursor: pointer;
	transition: border-color .15s ease, background-color .15s ease;
}

.hansdotter-date:hover:not(.is-full) {
	background: var(--wp--preset--color--custom-backgrund, #ecf3f1);
}

/* The checked row is marked by more than colour alone, so it still reads as
   chosen without relying on hue. */
.hansdotter-date:has(input:checked) {
	border-color: var(--wp--preset--color--custom-r-nder-logga, #727f78);
	border-width: 2px;
	padding: calc(.85rem - 1px) calc(1rem - 1px);
	background: var(--wp--preset--color--custom-backgrund, #ecf3f1);
}

.hansdotter-date input[type="radio"] {
	flex: 0 0 auto;
	margin: 0;
	accent-color: var(--wp--preset--color--custom-r-nder-logga, #727f78);
}

.hansdotter-date__name {
	flex: 1 1 auto;
}

.hansdotter-date__seats {
	flex: 0 0 auto;
	font-size: .85em;
	opacity: .75;
	white-space: nowrap;
}

.hansdotter-date.is-last .hansdotter-date__seats {
	opacity: 1;
	font-weight: 600;
	color: var(--wp--preset--color--custom-brun-rost, #b46a4f);
}

.hansdotter-date.is-full {
	opacity: .5;
	cursor: not-allowed;
}

.hansdotter-date.is-full .hansdotter-date__name {
	text-decoration: line-through;
}

@media (max-width: 600px) {
	.hansdotter-date {
		flex-wrap: wrap;
	}

	.hansdotter-date__seats {
		flex-basis: 100%;
		padding-left: 1.75rem;
	}
}


/* --- Produktsidan: bort med det som upprepar sig ---------------------------
   Three things the page says twice, or says at all when it should not.
   -------------------------------------------------------------------------- */

/* The tab bar, when there is one tab.
   mu-plugins/shop-chrome.php removes the additional-information and reviews
   tabs, which leaves a single "Beskrivning" tab sitting directly above a panel
   whose own heading also reads "Beskrivning". The panel stays; only the row of
   tabs goes, so nothing is lost but the duplication. */
.single-product .woocommerce-tabs ul.tabs.wc-tabs {
	display: none;
}

/* "1 i lager", printed under the date list once a date is chosen.
   Every row of that list already carries its own count ("4 platser kvar"),
   which is both more specific and visible before you commit to a date. Only the
   availability line is hidden — .single_variation also holds the PRICE, so
   hiding the container would take that with it. */
.single-product .woocommerce-variation-availability {
	display: none;
}

/* The "Rensa" link.
   Clicking a chosen date again now clears it, which is where a customer looks
   first. The link is hidden from sight but left in the accessibility tree
   rather than removed: a radio group cannot be un-selected from the keyboard,
   so without it there would be no way back for anyone not using a mouse. */
.single-product .reset_variations {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}


/* --- Mini-cart-ikonen -----------------------------------------------------
   WooCommerce renders the cart icon with the colour baked onto the SVG as a
   fill ATTRIBUTE — fill="#727f78" — taken from the block's stored value. The
   preset class it saves next to that value never reaches the markup, so the
   icon is not actually bound to the palette: changing the token in theme.json
   would move everything else and leave the cart behind.

   Pointing the fill at the variable puts it back under the palette's control.
   A presentation attribute loses to any CSS rule, so no !important is needed.
   -------------------------------------------------------------------------- */
.wc-block-mini-cart__button svg,
.wp-block-woocommerce-mini-cart svg {
	fill: var(--wp--preset--color--custom-r-nder-logga, #727f78);
}
