body.template-index .shopify-section.supafolio-book-carousel{margin-top:0;padding-top:40px;padding-bottom:120px;background-color:#FEE3D6}body.template-index .shopify-section.supafolio-book-carousel .page-width{max-width:900px}body.template-index #shopify-section-162634455493384 .grid__item{display:flex;flex-direction:column;text-align:center}body.template-index #shopify-section-162634455493384 .grid__item p,body.template-index #shopify-section-162634455493384 .grid__item h3{text-align:center}.js-supafolio-book-carousel-section .supafolio-grid-columns>a>img{transform:scale(0.95);transition:transform ease-in 0.2s}.js-supafolio-book-carousel-section .supafolio-grid-columns>a:hover>img{transform:scale(1)}.js-supafolio-book-carousel-section.flickity-enabled,.js-supafolio-book-carousel-section .flickity-viewport{overflow-y:visible}.product-form__other-links{display:none}

/* ---------------------------------------------------------------
   Full-bleed collection grids
   Mugs added 2026-08-03. Hover removed entirely 2026-08-06.
   Goodword Gifts, Book and Mug Gift Set and Inspirational Calendars
   (handle: inspirational-gifts) added 2026-08-27.

   Full-bleed images on white, and no motion on hover.
   The vendor rules being cancelled, from supadu.min.css.liquid:
     .supadu-product-grid__image
       { filter:drop-shadow(0 0 5px #222); transition:all .25s }
     .supadu-product-grid__item:hover .supadu-product-grid__image,
     .supadu-product-grid__item:focus .supadu-product-grid__image
       { transform:scale(1.1); filter:drop-shadow(0 0 8px #505050) }
   The hover pair scores 0,3,0 - adding the collection class makes 0,4,0
   and takes it. transition:none stops the scale animating back out on
   mouse-leave, which would otherwise still be visible for 250ms.

   All four collections share these three rules on purpose - listing them
   together is what stops one being changed and the others forgotten.
   To add another: add its .collection--<handle> line to each group.
   To revert: delete this whole block.
   --------------------------------------------------------------- */

.collection--inspirational-mug .supadu-product-grid__image-outer,
.collection--goodword-gifts .supadu-product-grid__image-outer,
.collection--book-and-mug .supadu-product-grid__image-outer,
.collection--inspirational-gifts .supadu-product-grid__image-outer{background-color:#fff;padding:0}

.collection--inspirational-mug .supadu-product-grid__image,
.collection--goodword-gifts .supadu-product-grid__image,
.collection--book-and-mug .supadu-product-grid__image,
.collection--inspirational-gifts .supadu-product-grid__image{width:100%;filter:none;transition:none}

.collection--inspirational-mug .supadu-product-grid__item:hover .supadu-product-grid__image,
.collection--inspirational-mug .supadu-product-grid__item:focus .supadu-product-grid__image,
.collection--goodword-gifts .supadu-product-grid__item:hover .supadu-product-grid__image,
.collection--goodword-gifts .supadu-product-grid__item:focus .supadu-product-grid__image,
.collection--book-and-mug .supadu-product-grid__item:hover .supadu-product-grid__image,
.collection--book-and-mug .supadu-product-grid__item:focus .supadu-product-grid__image,
.collection--inspirational-gifts .supadu-product-grid__item:hover .supadu-product-grid__image,
.collection--inspirational-gifts .supadu-product-grid__item:focus .supadu-product-grid__image{filter:none;transform:none}


/* ---- HOME PAGE ROW - GOODWORD GIFTS ONLY  (2026-08-27)
   The index page has no .collection--<handle> hook - that class is
   printed by sections/collection-template.liquid, which the home page
   never renders. So match the section by what it contains instead:
   product-grid-item builds each card's href as `product.url | within:
   collection`, so a home-page row for this collection is the only
   section whose cards link to /collections/goodword-gifts/products/.
   The VIEW ALL button and any nav link point at the collection root
   without /products/, so they do not match and other rows are untouched.
   Needs :has(); in an older browser the row just keeps the old style.
   To revert: delete this block. */

.shopify-section:has(a[href*="/collections/goodword-gifts/products/"]) .supadu-product-grid__image-outer{background-color:#fff;padding:0}
.shopify-section:has(a[href*="/collections/goodword-gifts/products/"]) .supadu-product-grid__image{width:100%;filter:none;transition:none}
.shopify-section:has(a[href*="/collections/goodword-gifts/products/"]) .supadu-product-grid__item:hover .supadu-product-grid__image,
.shopify-section:has(a[href*="/collections/goodword-gifts/products/"]) .supadu-product-grid__item:focus .supadu-product-grid__image{filter:none;transform:none}


/* ===============================================================
   ETSY PRODUCT PAGE - composed layout  (2026-08-07)

   Pairs with .etsy-info-column and the rail-slider script in
   snippets/etsy-product-template.liquid.
   To revert: delete this block AND undo that snippet.

   GUTTERS. One value, --gw-gutter, feeds BOTH the rail-to-hero gap and
   the hero-to-text gap, so the two are equal by construction and cannot
   drift apart when someone edits one and forgets the other.

   PROPORTION. Container 1350px, image column 49%, content 51%. Hero is
   column width minus the 74px rail minus one 60px gutter, so at 1270px
   of content the hero lands near 488px.

   SPECIFICITY. goodword-etsy.js injects <style id="gw-etsy-css"> into
   document.head at runtime - after every stylesheet - locking
   .left-column 35%, .middle-column 43%, .right-column 22% with
   !important. Written for the old flat 3-column DOM; nested inside
   .etsy-info-column they resolve against the column instead of the row
   and collapse the content. Their selector is 1 id + 1 class, so these
   chain BOTH wrapper ids for 2 ids and the win.

   PERMANENT FIX: delete those three width rules from gw-etsy-css and
   most of the !important flags below can go with them.
   =============================================================== */

#shopify-section-etsy-product-template{--gw-gutter:60px;--gw-rail:74px}

/* Centred container, equal air both sides. */
#shopify-section-etsy-product-template .page-content--product .page-width{max-width:1350px!important;margin-left:auto!important;margin-right:auto!important;padding-left:40px!important;padding-right:40px!important}

@media (min-width: 769px){

/* nowrap prevents a second row whatever the vendor rules do; order
     pins images left because .grid--product-images-right is always
     applied (the section passes image_position from a setting the Etsy
     schema never defines, so it is nil and never equals 'left'). */
#shopify-section-etsy-product-template .supadu-product-details{display:flex;flex-wrap:nowrap;align-items:flex-start}

#shopify-section-etsy-product-template #shopify-section-supadu-product-template .supadu-product-details>.left-column{width:49%!important;max-width:49%!important;flex:0 0 49%!important;order:1;padding-left:0!important;padding-right:0!important}
#shopify-section-etsy-product-template #shopify-section-supadu-product-template .supadu-product-details>.etsy-info-column{width:51%!important;max-width:51%!important;flex:0 0 51%!important;order:2;padding-left:var(--gw-gutter)!important}

/* Nested columns are plain blocks now - fill the info column instead
     of taking 43% / 22% of it. */
#shopify-section-etsy-product-template #shopify-section-supadu-product-template .etsy-info-column>.middle-column,
#shopify-section-etsy-product-template #shopify-section-supadu-product-template .etsy-info-column>.right-column{width:100%!important;max-width:100%!important;flex:0 0 auto!important;margin-left:0!important;padding-left:0!important}

/* Buy box at 61.8% of its column. Sticky off - the column is short
     enough now that sticking just makes it drift. */
#shopify-section-etsy-product-template #shopify-section-supadu-product-template .etsy-info-column .product-form__sticky{position:static!important;width:61.8%!important;max-width:61.8%!important}
#shopify-section-etsy-product-template .etsy-info-column>.right-column{margin-top:34px!important}
}

/* The floating book thumbnail faded in during sticky scroll, is absolutely
   positioned at top:-75px, and has nothing to anchor to now. */
#shopify-section-etsy-product-template .etsy-info-column .product-form__book{display:none!important}


/* ---- GALLERY RAIL --------------------------------------------
   goodword-etsy.js gives .gw-et-rail a FIXED max-height:760px, unrelated
   to the hero beside it - so the strip's length was decided by how many
   photos exist and ran past the bottom of the image.

   Absolute positioning inside .gw-et-wrap makes the HERO define the
   height, so the rail always ends exactly level with the image.

   space-between handles the other direction. When the thumbnails do NOT
   fill the hero's height - seven tiles against a 488px hero leaves about
   50px spare - they would otherwise bunch at the top and stop short. It
   pins the first tile to the top and the last to the bottom and spreads
   the slack across the gaps. When there are enough photos to overflow
   there is no free space, so it has no effect and the rail simply
   scrolls as before.

   TWO selectors on purpose. The script in the snippet wraps the rail in
   .gw-rail-col to add the chevrons; the direct-child selector
   .gw-et-wrap > .gw-et-rail only matches when it has NOT been wrapped.
   So bottom alignment is pure CSS and holds even if that script fails,
   is blocked, or runs late - the arrows are an enhancement on top, not
   a requirement for the layout to be correct.
   Engine rules here are not !important, so one id is enough to win. */
@media (min-width: 769px){
#shopify-section-etsy-product-template .gw-et-wrap{position:relative;display:block}
#shopify-section-etsy-product-template .gw-et-hero{margin-left:calc(var(--gw-rail) + var(--gw-gutter))}

/* Unwrapped - script has not run (yet). */
#shopify-section-etsy-product-template .gw-et-wrap>.gw-et-rail{position:absolute;left:0;top:0;bottom:0;width:var(--gw-rail);max-height:none;overflow-y:auto;scrollbar-width:none;justify-content:space-between}

/* Wrapped - script has run, chevrons present. */
#shopify-section-etsy-product-template .gw-rail-col{position:absolute;left:0;top:0;bottom:0;width:var(--gw-rail);display:flex;flex-direction:column}
#shopify-section-etsy-product-template .gw-rail-col>.gw-et-rail{position:static;flex:1 1 auto;min-height:0;max-height:none;width:var(--gw-rail);overflow-y:auto;scrollbar-width:none;justify-content:space-between}

#shopify-section-etsy-product-template .gw-et-rail::-webkit-scrollbar{display:none}

/* Arrows exist only when there is somewhere to go. */
#shopify-section-etsy-product-template .gw-rail-nav{display:none;flex:0 0 26px;height:26px;width:var(--gw-rail);align-items:center;justify-content:center;border:1px solid #e3e3e3;border-radius:8px;background:#fff;color:#222;cursor:pointer;padding:0;transition:border-color .15s,opacity .15s}
#shopify-section-etsy-product-template .gw-rail-col.is-scrollable .gw-rail-nav{display:flex}
#shopify-section-etsy-product-template .gw-rail-col.is-scrollable>.gw-et-rail{margin:8px 0}
#shopify-section-etsy-product-template .gw-rail-nav:hover{border-color:#999}
#shopify-section-etsy-product-template .gw-rail-nav.is-off{opacity:.3;pointer-events:none}
}


/* ---- MOBILE --------------------------------------------------
   Below 769px the engine flips the rail horizontal under the hero and
   the columns stack. Three corrections:

   1. The slider arrows were hidden by a rule that lived INSIDE the
      min-width:769px query, so on phones they fell back to the browser
      default for <button> and rendered as loose chevrons above and below
      the thumbnail strip. display:contents keeps the rail behaving as if
      it were never wrapped.

   2. Image first. On a phone the photograph has to lead - a gift buyer
      decides on the picture, not the headline.

   3. 32px headline is a desktop size; on a 390px screen it ran to four
      lines and pushed the price below the fold.
   -------------------------------------------------------------- */
@media (max-width: 768px){
#shopify-section-etsy-product-template .gw-rail-col{display:contents}
#shopify-section-etsy-product-template .gw-rail-nav{display:none!important}
#shopify-section-etsy-product-template .gw-et-hero{margin-left:0}

#shopify-section-etsy-product-template .supadu-product-details{display:flex;flex-direction:column}
#shopify-section-etsy-product-template .supadu-product-details>.left-column{order:1}
#shopify-section-etsy-product-template .supadu-product-details>.etsy-info-column{order:2}

#shopify-section-etsy-product-template .page-content--product .page-width{padding-left:20px!important;padding-right:20px!important}
}


/* ---- TYPE ----------------------------------------------------
   goodword-etsy.js writes inline font sizes in renderMiddle(), so these
   need !important to land. text-wrap:balance evens the h1 across its
   lines instead of leaving one orphan word - no hardcoded <br>, so it
   works for every product title, long or short. */
#shopify-section-etsy-product-template .middle-column .product__title{font-size:32px!important;line-height:1.18!important;margin:0 0 8px!important;text-wrap:balance}
#shopify-section-etsy-product-template .middle-column .product-vendor{font-size:15px!important;margin:13px 0 0!important}
#shopify-section-etsy-product-template .middle-column .product__price{font-size:28px!important;font-weight:700!important}

/* Description fills the column so its right edge lines up with the
   container - part of the left/right balance fix. */
#shopify-section-etsy-product-template .middle-column .product__description{max-width:none;font-size:17px!important;line-height:1.75!important;margin-top:21px!important}
#shopify-section-etsy-product-template .middle-column .product__description>span{-webkit-line-clamp:3!important}

/* Mobile type overrides sit AFTER the desktop block so they win on equal
   specificity - media queries do not add any. */
@media (max-width: 768px){
#shopify-section-etsy-product-template .middle-column .product__title{font-size:24px!important;line-height:1.22!important}
#shopify-section-etsy-product-template .middle-column .product__price{font-size:24px!important}
}


/* ---- BUY BOX - COLOUR-VARIANT PRODUCTS ONLY  (2026-08-27)
   White card, no outline. Scoped to :has(#gw-color-block) - the engine
   injects that div only when the product has colours, so plain books are
   untouched. Desktop and mobile alike.
   To revert: delete this whole block. */

#shopify-section-etsy-product-template:has(#gw-color-block) .etsy-info-column .product-form__sticky,
#shopify-section-etsy-product-template:has(#gw-color-block) .etsy-info-column .product-form__inner,
#shopify-section-etsy-product-template:has(#gw-color-block) .etsy-info-column .product-form__switch-format,
#shopify-section-etsy-product-template:has(#gw-color-block) .etsy-info-column #gw-color-block,
#shopify-section-etsy-product-template:has(#gw-color-block) .etsy-info-column #gw-format-label{background:#fff!important}

#shopify-section-etsy-product-template:has(#gw-color-block) #gw-format-label>div{border-color:#cfd8dc!important}

/* renderRight() bails on `if (!book.format) return;` BEFORE it hides the
   theme's own format dropdown, so with no format that empty box is left
   on screen above the colours. :empty hides it only when it has no
   content, so a dropdown the supadu script fills still shows. */
#shopify-section-etsy-product-template .js-formats-dropdown:empty{display:none!important}

#shopify-section-etsy-product-template #gw-color-swatches{flex-wrap:nowrap!important;gap:8px!important}
#shopify-section-etsy-product-template #gw-color-swatches>div{width:auto!important;flex:1 1 0!important;min-width:0!important}
#shopify-section-etsy-product-template #gw-color-swatches .gw-sw{width:100%!important;max-width:40px!important;height:auto!important;aspect-ratio:1/1!important}