/* Theme base styles */
/* bundle: 2026-08-04c — see sop/build/B-02, Trap 0b. Editing an INCLUDED partial
   does not reliably regenerate template_main.min.css; the bundle keeps serving
   old CSS under an unchanged version string. Touching this file does. */

/* Tools
Any animations, or functions used throughout the project.
Note: _macros.css needs to be imported into each stylesheet where macros are used and not included here
*/

/* Generic
This is where reset, normalize & box-sizing styles go.
*/

*, *:before, *:after {
  box-sizing: border-box;
}
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */

/* Document
   ========================================================================== */

/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */

html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
   ========================================================================== */

/**
 * Remove the margin in all browsers.
 */

body {
  margin: 0;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
   ========================================================================== */

/**
 * Add the correct box sizing in Firefox.
 */

hr {
  box-sizing: content-box;
  height: 0;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

pre {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/* Text-level semantics
   ========================================================================== */

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
 */

abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  text-decoration: underline dotted; /* 2 */
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */

b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

code,
kbd,
samp {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/**
 * Add the correct font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Forms
   ========================================================================== */

/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Remove the inheritance of text transform in Edge and Firefox.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select { /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */

fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * Remove the padding so developers are not caught out when they zero out `fieldset` elements in all browsers.
 */

legend {
  padding: 0;
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */

progress {
  vertical-align: baseline;
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */

[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */

[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */

[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/* Interactive
   ========================================================================== */

/*
 * Add the correct display in Edge and Firefox.
 */

details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */

summary {
  display: list-item;
}

/* Objects
Non-cosmetic design patterns including grid and layout classes)
*/



/* CSS variables */

:root {
  --column-gap: 2.13%;
  --column-width-multiplier: 8.333;
}

/* Mobile layout */

.row-fluid {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
}


  .row-fluid .span1,
  .row-fluid .span2,
  .row-fluid .span3,
  .row-fluid .span4,
  .row-fluid .span5,
  .row-fluid .span6,
  .row-fluid .span7,
  .row-fluid .span8,
  .row-fluid .span9,
  .row-fluid .span10,
  .row-fluid .span11,
  .row-fluid .span12{
  min-height: 1px;
  width: 100%;
}

/* Desktop layout */

@media (min-width: 768px) {
  .row-fluid {
    flex-wrap: nowrap;
    justify-content: space-between;
  }

  
    .row-fluid .span1 {
      width: calc(var(--column-width-multiplier) * 1% * 1 - var(--column-gap) * (11 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span2 {
      width: calc(var(--column-width-multiplier) * 1% * 2 - var(--column-gap) * (10 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span3 {
      width: calc(var(--column-width-multiplier) * 1% * 3 - var(--column-gap) * (9 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span4 {
      width: calc(var(--column-width-multiplier) * 1% * 4 - var(--column-gap) * (8 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span5 {
      width: calc(var(--column-width-multiplier) * 1% * 5 - var(--column-gap) * (7 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span6 {
      width: calc(var(--column-width-multiplier) * 1% * 6 - var(--column-gap) * (6 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span7 {
      width: calc(var(--column-width-multiplier) * 1% * 7 - var(--column-gap) * (5 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span8 {
      width: calc(var(--column-width-multiplier) * 1% * 8 - var(--column-gap) * (4 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span9 {
      width: calc(var(--column-width-multiplier) * 1% * 9 - var(--column-gap) * (3 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span10 {
      width: calc(var(--column-width-multiplier) * 1% * 10 - var(--column-gap) * (2 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span11 {
      width: calc(var(--column-width-multiplier) * 1% * 11 - var(--column-gap) * (1 * var(--column-width-multiplier) / 100));
    }
  
}
.content-wrapper {
  margin: 0 auto;
  padding: 0 1rem;
}

@media screen and (min-width: 1380px) {
  .content-wrapper {
    padding: 0;
  }
}

.dnd-section > .row-fluid {
  margin: 0 auto;
}

.dnd-section .dnd-column {
  padding: 0 1rem;
}

@media (max-width: 767px) {
  .dnd-section .dnd-column {
    padding: 0;
  }
}

/* Elements
Base HTML elements are styled in this section (<body>, <h1>, <a>, <p>, <button> etc.)
*/

/* The overflow-wrap is meant to prevent long/large words from breaking the mobile responsiveness of a page (e.g. horizontal scrolling). It is preferred to reduce font sizes on mobile to address this, with this CSS specifically helping with extreme scenarios where a reduction in font size is not possible. */

body {
  line-height: 1.4;
  overflow-wrap: break-word;
}

/* Handles word breaking for a few specific languages which handle breaks in words differently. If your content is not translated into these languages, you can safely remove this.  */

html[lang^="ja"] body,
html[lang^="zh"] body,
html[lang^="ko"] body {
  line-break: strict;
  overflow-wrap: normal;
  word-break: break-all;
}

/* Paragraphs */

p {
  font-size: 1rem;
  margin: 0 0 1.4rem;
}

/* Anchors */

a {
  cursor: pointer;
}

/* Headings */

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0 0 1.4rem;
}

/* Lists */

ul,
ol {
  margin: 0 0 1.4rem;
}

ul ul,
ol ul,
ul ol,
ol ol {
  margin: 0;
}

ul.no-list {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* Code blocks */

pre {
  overflow: auto;
}

code {
  vertical-align: bottom;
}

/* Blockquotes */

blockquote {
  border-left: 2px solid;
  margin: 0 0 1.4rem;
  padding-left: 0.7rem;
}

/* Horizontal rules */

hr {
  border: none;
  border-bottom: 1px solid #CCC;
}

/* Image alt text */

img {
  font-size: 0.583rem;
  word-break: normal;
}
button,
.button,
.hs-button {
  cursor: pointer;
  display: inline-block;
  text-align: center;
  transition: all 0.15s linear;
  white-space: normal;
}

button:disabled,
.button:disabled,
.hs-button:disabled {
  background-color: #D0D0D0;
  border-color: #D0D0D0;
  color: #E6E6E6;
}

/* No button */

.no-button,
.no-button:hover,
.no-button:focus,
.no-button:active {
  background: none;
  border: none;
  border-radius: 0;
  color: initial;
  font-family: inherit;
  font-size: inherit;
  font-style: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  margin-bottom: 0;
  padding: 0;
  text-align: left;
  text-decoration: none;
  transition: none;
}
/* Fields */

.hs-form-field {
  margin-bottom: 1.4rem;
}

/* Labels */

form label {
  display: block;
  font-size: 0.875rem;
  margin-bottom: 0.35rem;
}

/* Form Title */
.form-title {
  margin-bottom: 0;
}

/* Help text */

form legend {
  font-size: 0.875rem;
}

/* Inputs */

form input[type=text],
form input[type=search],
form input[type=email],
form input[type=password],
form input[type=tel],
form input[type=number],
form input[type=file],
form select,
form textarea {
  display: inline-block;
  font-size: 0.875rem;
  padding: 0.7rem;
  width: 100%;
}

form textarea {
  resize: vertical;
}

form fieldset {
  max-width: 100% !important;
}

/* Inputs - checkbox/radio */

form .inputs-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

form .inputs-list > li {
  display: block;
  margin: 0.7rem 0;
}

form .inputs-list input,
form .inputs-list span {
  vertical-align: middle;
}

form input[type=checkbox],
form input[type=radio] {
  cursor: pointer;
  margin-right: 0.35rem;
}

/* Inputs - date picker */

.hs-dateinput {
  position: relative;
}

.hs-dateinput:before {
  content:'\01F4C5';
  position: absolute;
  right: 10%;
  top: 50%;
  transform: translateY(-50%);
}

.fn-date-picker .pika-table thead th {
  color: #FFF;
}

.fn-date-picker td.is-selected .pika-button {
  border-radius: 0;
  box-shadow: none;
}

.fn-date-picker td .pika-button:hover,
.fn-date-picker td .pika-button:focus {
  border-radius: 0 !important;
  color: #FFF;
}

/* Inputs - file picker */

form input[type=file] {
  background-color: transparent;
  border: initial;
  padding: initial;
}

/* Headings and text */

form .hs-richtext,
form .hs-richtext p {
  font-size: 0.875rem;
  margin: 0 0 1.4rem;
}

form .hs-richtext img {
  max-width: 100% !important;
}

/* GDPR */

.legal-consent-container .hs-form-booleancheckbox-display > span,
.legal-consent-container .hs-form-booleancheckbox-display > span p {
  margin-left: 1rem !important;
}

/* Validation */

.hs-form-required {
  color: #EF6B51;
}

.hs-input.invalid.error {
  border-color: #EF6B51;
}

.hs-error-msg {
  color: #EF6B51;
  margin-top: 0.35rem;
}

/* Submit button */

form input[type=submit],
form .hs-button {
  cursor: pointer;
  display: inline-block;
  text-align: center;
  transition: all 0.15s linear;
  white-space: normal;
}

/* Captcha */

.grecaptcha-badge {
  margin: 0 auto;
}


  /* Search button input field and suggestions */
  .body-container-wrapper .hs-search-field__button {
    padding: 15px;
  }

  .body-container-wrapper .hs-search-field__bar--button-inline .hs-search-field__button {
    margin-left: 6px;
    margin-bottom: 0;
  }

  .body-container-wrapper .hs-search-field__button svg {
    height: 15px;
    fill: #fff;
  }

  .body-container-wrapper .hs-search-field__bar > form > .hs-search-field__input {
    padding: 10px;
  }

  .body-container-wrapper .hs-search-field__suggestions li a {
    color: #494A52;
    padding: 0.35rem 0.7rem;
    text-decoration: none;
    transition: background-color 0.3s;
  }

/* Table */

table {
  border-collapse: collapse;
  margin-bottom: 1.4rem;
  overflow-wrap: break-word;
}

/* Table cells */

td,
th {
  vertical-align: top;
}

/* Table header */

thead th {
  vertical-align: bottom;
}

/* Components
Specific pieces of UI that are stylized. Typically used for global partial styling
*/

/* Header DND sections */

.header .dnd-section {
  padding: 0;
}

/* Header container */

.header__container {
  display: flex;
  justify-content: space-between;
}

.header__row-1 {
  padding-top: 1rem;
}

.header__row-1,
.header__row-2 {
  align-items: center;
  display: flex;
  justify-content: flex-end;
  width: 100%;
}

@media (max-width: 1150px) and (min-width: 767px) {
  .header__column {
    width: 100%;
  }
}

@media (max-width: 767px) {
  .header__container {
    flex-direction: column;
    padding: 1rem 0 0;
  }

  .header__column {
    position: relative;
  }

  .header__row-1 {
    padding-top: 0;
  }

  .header__row-2 {
    justify-content: center;
    padding: 1.05rem;
  }
}

/* Navigation skipper */

.header__skip {
  height: 1px;
  left: -1000px;
  overflow: hidden;
  position: absolute;
  text-align: left;
  top: -1000px;
  width: 1px;
}

.header__skip:hover,
.header__skip:focus,
.header__skip:active {
  height: auto;
  left: 0;
  overflow: visible;
  top: 0;
  width: auto;
}

/* Logo */

.header__logo {
  align-items: center;
  display: flex;
  height: auto;
  margin-right: auto;
  max-width: 200px;
  overflow: hidden;
}

@media (max-width: 767px) {
  .header__logo {
    margin: 0 auto;
    width: 100%;
  }
}

.header__logo img {
  max-width: 100%;
}

.header__logo .logo-company-name {
  font-size: 1.167rem;
  margin-top: 0.7rem;
}

.header__logo--main {
  padding-top: 1rem;
}

/* Search bar */

.header__search {
  padding: 0 1rem;
  width: auto;
}



  .hs-search-field__form {
    position: relative;
  }

  .header__search .hs-search-field__label {
    flex-basis: auto;
  }



.header__search .hs-search-field__input {
  
  height: 45px;
  padding: 0 0.7rem;
}



  .header__search .hs-search-field__button {
    padding: 0;
    fill: #000;
    background-color: transparent;
    border: none;
    padding: 10px;
    position: absolute;
    top: 0;
    right: 0;
  }

  .header__search .hs-search-field__button svg {
    height: 25px;
  }


.header__search .hs-search-field--open .hs-search-field__input {
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  max-width: 100%;
}

.header__search .hs-search-field--open .hs-search-field__suggestions {
  background-color: #FFF;
  border: 2px solid #D1D6DC;
  border-radius: 0 0 6px 6px;
  border-top-width: 1px;
  position: absolute;
  width: 100%;
  z-index: 10;
}

.header__search .hs-search-field__suggestions li {
  border-top: 1px solid #D1D6DC;
  font-size: 0.875rem;
}

.header__search .hs-search-field__suggestions li a {
  color: #494A52;
  padding: 0.35rem 0.7rem;
  text-decoration: none;
  transition: background-color 0.3s;
}

.header__search .hs-search-field__suggestions #results-for {
  display: none;
}

@media (min-width: 767px) {
  .header__search form {
    align-items: center;
    display: flex;
    flex-direction: row;
  }

  .header__search label {
    margin: 0 1rem 0 0;
  }

  .header__search .hs-search-field__input {
    width: auto;
  }
}

@media (max-width: 767px) {
  .header__search {
    border-top: 2px solid #CED4DB;
    order: 1;
    padding: 1.05rem;
  }
}

/* Language switcher */

.header__language-switcher {
  cursor: pointer;
  padding-right: 1.4rem;
}

.header__language-switcher .lang_switcher_class {
  position: static;
}

.header__language-switcher .lang_list_class {
  border: 2px solid;
  border-radius: 3px;
  box-shadow: 0 2px 9px 0 rgba(0, 0, 0, 0.2);
  display: block;
  left: calc(100% - 24px);
  opacity: 0;
  min-width: 100px;
  padding-top: 0;
  text-align: left;
  top: 100%;
  transition: opacity 0.3s;
  visibility: hidden;
}

.header__language-switcher:hover .lang_list_class,
.header__language-switcher:focus .lang_list_class {
  opacity: 1;
  transition: opacity 0.3s;
  visibility: visible;
}

.header__language-switcher .lang_list_class:before {
  left: 70%;
  top: -25px;
}

.header__language-switcher .lang_list_class:after {
  left: 70%;
  top: -22px;
}

.header__language-switcher .lang_list_class.first-active::after {
  top: -22px;
  transition: 0.3s;
}

.header__language-switcher .lang_list_class li {
  border: none;
  font-size: 18px;
  padding: 0.35rem 0.7rem;
}

.header__language-switcher .lang_list_class li:first-child {
  border-radius: 6px 6px 0 0;
  border-top: none;
}

.header__language-switcher .lang_list_class li:last-child {
  border-bottom: none;
  border-radius: 0 0 6px 6px;
}

.header__language-switcher .lang_list_class li:hover {
  transition: background-color 0.3s;
}

.header__language-switcher--label {
  display: flex;
  position: relative;
}

.header__language-switcher--label-current {
  align-items: center;
  display: flex;
  font-size: 0.75rem;
  margin-bottom: 0.175rem;
  margin-left: 0.7rem;
}

.header__language-switcher--label-current:after {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 6px solid #494A52;
  content: "";
  display: block;
  height: 0px;
  margin-left: 0.7rem;
  margin-top: 0.175rem;
  width: 0px;
}

@media (max-width: 767px) {
  .header__language-switcher {
    border-top: 2px solid #CED4DB;
    padding-left: 1.05rem;
    padding-right: 0;
  }

  .header__language-switcher .lang_list_class {
    border: none;
    box-shadow: unset;
    display: block;
    left: 30px;
    opacity: 1;
    padding: 0 1.05rem;
    top: 0;
    visibility: visible;
  }

  .header__language-switcher .lang_list_class li {
    background-color: inherit;
    font-size: 0.917rem;
  }

  .header__language-switcher--label-current {
    display: none;
  }

  .header__language-switcher .globe_class {
    background-image: none;
  }

  .header__language-switcher .lang_list_class li:hover{
    background-color: inherit;
  }

  .header__language-switcher .lang_list_class:before,
  .header__language-switcher .lang_list_class:after {
    content: none;
  }
    /* V1 lang switcher updates to keep "in line" w/ v0 mobile styles */
    .header__language-switcher .hs-language-switcher__menu {
        display: block;
        box-shadow:none!important;
        background: transparent;
    }
    .header__language-switcher .hs-language-switcher__menu a {
        font-size: 20px!important;
    }
    .header__language-switcher .hs-language-switcher__button {
        display: none;
    }
  }

/* Navigation */

#nav-toggle {
  display: none;
}

/* Mobile toggles */

@media (max-width: 767px) {
  .header__navigation,
  .header__search,
  .header__language-switcher {
    display: none;
    width: 100%;
  }

  .header__navigation.open,
  .header__search.open,
  .header__language-switcher.open {
    background-color: #F8FAFC;
    display: block;
    left: 0;
    min-height: calc(100vh - 115px);
    position: absolute;
    right: 0;
    top: 75px;
    z-index: 2;
  }

  .header__navigation--toggle,
  .header__search--toggle,
  .header__language-switcher--toggle,
  .header__close--toggle {
    cursor: pointer;
    margin: 0 5vw;
    position: relative;
  }

  .header__navigation--toggle.hide,
  .header__search--toggle.hide,
  .header__language-switcher--toggle.hide {
    display: none;
  }

  .header__navigation--toggle.open,
  .header__search--toggle.open,
  .header__language-switcher--toggle.open {
    display: block;
    margin-left: 0;
    margin-right: auto;
  }

  .header__navigation--toggle:after,
  .header__search--toggle:after,
  .header__language-switcher--toggle:after {
    display: none;
    font-size: 1.083rem;
    font-weight: 600;
    position: absolute;
    left: 40px;
    text-transform: uppercase;
    top: -10px;
  }

  .header__navigation--toggle.open:after,
  .header__search--toggle.open:after,
  .header__language-switcher--toggle.open:after {
    display: block;
    word-break: normal;
  }

  .header__navigation--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAxOSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5oYW1idXJnZXI8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGcgaWQ9ImhhbWJ1cmdlciIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgICAgICA8ZyBpZD0iR3JvdXAiIHN0cm9rZT0iIzQ5NEE1MiIgc3Ryb2tlLXdpZHRoPSIzIj4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiB4PSIxLjUiIHk9IjEuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLUNvcHktNCIgeD0iMS41IiB5PSI5LjUiIHdpZHRoPSIyMSIgaGVpZ2h0PSIxIiByeD0iMC41Ij48L3JlY3Q+ICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS1Db3B5LTUiIHg9IjEuNSIgeT0iMTcuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__navigation--toggle:after {
    content: "Menu";
  }

  .header__language-switcher--toggle {
    background-image: url(//static.hsappstatic.net/cos-LanguageSwitcher/static-1.1/img/globe.png);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__language-switcher--toggle:after {
    content: "Language";
  }

  .header__search--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5TZWFyY2g8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+ICAgICAgICA8cGF0aCBkPSJNOS4xMzg2MTUzNCwxNS44OTI1Njg1IEM1LjQxMzk1NzQyLDE1Ljg5MjU2ODUgMi4zODM4ODUyNywxMi44NjM0NDc1IDIuMzgzODg1MjcsOS4xMzkwMDM3NiBDMi4zODM4ODUyNyw1LjQxNDU2MDA1IDUuNDEzOTU3NDIsMi4zODM4ODUyNyA5LjEzODYxNTM0LDIuMzgzODg1MjcgQzEyLjg2MzI3MzMsMi4zODM4ODUyNyAxNS44OTI1Njg1LDUuNDE0NTYwMDUgMTUuODkyNTY4NSw5LjEzOTAwMzc2IEMxNS44OTI1Njg1LDEyLjg2MzQ0NzUgMTIuODYzMjczMywxNS44OTI1Njg1IDkuMTM4NjE1MzQsMTUuODkyNTY4NSBNOS4xMzg3NTI0NSwyLjQzMzYwODg3ZS0xMyBDMTQuMTc3OTk1NSwyLjQzMzYwODg3ZS0xMyAxOC4yNzY0NTM3LDQuMTAwMzI0NzEgMTguMjc2NDUzNyw5LjEzOTI3Nzk2IEMxOC4yNzY0NTM3LDExLjIyOTgyMTEgMTcuNTcxMDE2OSwxMy4xNTg0NDM0IDE2LjM4NTYzMTMsMTQuNjk5NjY5NiBMMjMuNjUwODg4MSwyMS45NjUyMjY2IEMyNC4xMTYzNzA2LDIyLjQzMDcwOTIgMjQuMTE2MzcwNiwyMy4xODU0MDU1IDIzLjY1MDg4ODEsMjMuNjUwODg4MSBDMjMuMTg1NDA1NSwyNC4xMTYzNzA2IDIyLjQzMDcwOTIsMjQuMTE2MzcwNiAyMS45NjUyMjY2LDIzLjY1MDg4ODEgTDE0LjY5OTgxMzMsMTYuMzg1NDcxMyBDMTMuMTU4NDQwNSwxNy41NzA5NTA5IDExLjIyOTU3MzgsMTguMjc2NDUzNyA5LjEzODc1MjQ1LDE4LjI3NjQ1MzcgQzQuMDk5NTA5MzgsMTguMjc2NDUzNyAtMy43MzAzNDkzNmUtMTQsMTQuMTc4MjMxMiAtMy43MzAzNDkzNmUtMTQsOS4xMzkyNzc5NiBDLTMuNzMwMzQ5MzZlLTE0LDQuMTAwMzI0NzEgNC4wOTk1MDkzOCwyLjQzMzYwODg3ZS0xMyA5LjEzODc1MjQ1LDIuNDMzNjA4ODdlLTEzIFoiIGlkPSJwYXRoLTEiPjwvcGF0aD4gICAgPC9kZWZzPiAgICA8ZyBpZD0iU2VhcmNoIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4gICAgICAgIDxtYXNrIGlkPSJtYXNrLTIiIGZpbGw9IndoaXRlIj4gICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPiAgICAgICAgPC9tYXNrPiAgICAgICAgPHVzZSBpZD0iSWNvbnMvQWN0aW9ucy9TZWFyY2giIGZpbGw9IiM0OTRBNTIiIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPiAgICA8L2c+PC9zdmc+);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__search--toggle:after {
    content: "Search";
  }

  .header__close--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjE5cHgiIHZpZXdCb3g9IjAgMCAyNCAxOSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5jbG9zZTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZyBpZD0iY2xvc2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyLjAwMDAwMCwgLTEuMDAwMDAwKSIgc3Ryb2tlPSIjNDk0QTUyIiBzdHJva2Utd2lkdGg9IjMiPiAgICAgICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwLjAwMDAwMCwgMTAuNTAwMDAwKSByb3RhdGUoLTQ1LjAwMDAwMCkgdHJhbnNsYXRlKC0xMC4wMDAwMDAsIC0xMC41MDAwMDApICIgeD0iLTAuNSIgeT0iMTAuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLUNvcHktNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAuMDAwMDAwLCAxMC41MDAwMDApIHJvdGF0ZSg0NS4wMDAwMDApIHRyYW5zbGF0ZSgtMTAuMDAwMDAwLCAtMTAuNTAwMDAwKSAiIHg9Ii0wLjUiIHk9IjEwLjUiIHdpZHRoPSIyMSIgaGVpZ2h0PSIxIiByeD0iMC41Ij48L3JlY3Q+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=);
    background-repeat: no-repeat;
    background-size: 110%;
    display: none;
    height: 25px;
    margin-right: 0;
    width: 25px;
  }

  .header__close--toggle.show {
    display: block;
  }
}
/* Menu and simple menu */

.hs-menu-wrapper ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* Horizontal menu */

.hs-menu-wrapper.hs-menu-flow-horizontal .hs-menu-children-wrapper {
  flex-direction: column;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.hs-menu-flow-horizontal ul {
    flex-direction: column;
  }
}

/* Vertical menu */

.hs-menu-wrapper.hs-menu-flow-vertical ul {
  flex-direction: column;
}

/* Flyouts */

.hs-menu-wrapper.hs-menu-flow-vertical.flyouts ul {
  display: inline-flex;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.hs-menu-flow-vertical ul {
    display: flex;
  }
}

.hs-menu-wrapper.flyouts .hs-item-has-children {
  position: relative;
}

.hs-menu-wrapper.flyouts .hs-menu-children-wrapper {
  left: -9999px;
  opacity: 0;
  position: absolute;
}

.hs-menu-wrapper.flyouts .hs-menu-children-wrapper a {
  display: block;
  white-space: nowrap;
}

.hs-menu-wrapper.hs-menu-flow-horizontal.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
  left: 0;
  opacity: 1;
  top: 100%;
}

.hs-menu-wrapper.hs-menu-flow-vertical.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
  left: 100%;
  opacity: 1;
  top: 0;
}

@media (max-width: 767px) {
  .hs-menu-wrapper.flyouts .hs-menu-children-wrapper,
  .hs-menu-wrapper.hs-menu-flow-horizontal.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper,
  .hs-menu-wrapper.hs-menu-flow-vertical.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
    left: 0;
    opacity: 1;
    position: relative;
    top: auto;
  }
}

/* CTA, logo, and rich text images */

.hs_cos_wrapper_type_cta img,
.hs_cos_wrapper_type_logo img,
.hs_cos_wrapper_type_rich_text img {
  height: auto;
  max-width: 100%;
}

/* Utilities
Helper classes with ability to override anything that comes before it
*/

/* For content that needs to be visually hidden but stay visible for screenreaders */

.show-for-sr {
  border: 0 !important;
  clip: rect(0, 0, 0, 0) !important;
  height: 1px !important;
  overflow: hidden !important;
  padding: 0 !important;
  position: absolute !important;
  white-space: nowrap !important;
  width: 1px !important;
}

@media (max-width: 767px) {
  .show-for-sr--mobile {
    border: 0 !important;
    clip: rect(0, 0, 0, 0) !important;
    height: 1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    white-space: nowrap !important;
    width: 1px !important;
  }
}

/* ==========================================================================
   Glow design system
   Bundled here rather than per-template. Two reasons: get_asset_url in
   layouts/base.html resolves relative to the layout, not the page, so
   per-template paths were silently producing href="" — and at 51KB total the
   whole system costs less than the extra request. Every page therefore has
   every glow class available, which also removes the cross-file dependencies
   (.glow-index lives in _home.css but the treatments index needs it).
   Order matters: tokens first, then base, then chrome, then page layers.
   ========================================================================== */

/* ==========================================================================
   Glow Cosmetique — design tokens
   Single source of truth. Change a value here, it changes everywhere.

   Direction: warm and editorial rather than cool and austere. Serif display,
   soft tinted grounds, deep warm field for contrast. Composition does the
   work — no shadows, no gradients, no decoration.
   ========================================================================== */

:root {
  /* ---- Colour ---------------------------------------------------------
     Warmed from the group palette. Burgundy remains the accent and now
     also anchors the deep field, which ties the site to the clinic's
     own colour rather than a borrowed slate. */
  --glow-cream:      #FAF7F2;   /* page background */
  --glow-blush:      #F4EAE2;   /* tinted card / soft ground */
  --glow-light:      #EFE6DC;   /* secondary surface */
  --glow-border:     #E2D6C9;   /* hairlines */
  --glow-ink:        #241C1A;   /* primary text — warm near-black */
  --glow-ink-soft:   #4A3E39;   /* body text */
  --glow-muted:      #7A6A62;   /* secondary text */
  --glow-deep:       #33211F;   /* deep field — footer, contrast blocks */
  --glow-burgundy:   #6D2932;   /* accent */
  --glow-sage:       #41493E;   /* secondary accent, used rarely */
  --glow-white:      #FFFFFF;

  /* ---- Attention, and ONLY attention -----------------------------------
     Added 3 Aug 2026. Burgundy was doing two jobs — brand accent AND "outside
     the expected range" — so a section heading, a link and a flagged marker all
     read at the same weight on a page carrying 62 rows. Amber now means one
     thing: LOOK HERE. Burgundy goes back to meaning Glow.

     Deliberately no green. Green would mean "good", which is a verdict the
     clinic has not given — and on a hormone panel "in range" is not a pass mark,
     it is a description. Amber is the only signal colour on the page, and its
     worst case is still amber. */
  --glow-flag:       #A8641E;   /* out of range — 4.9:1 on cream */
  --glow-flag-soft:  #F6EBDC;   /* its tint */
  --glow-flag-line:  #E3CBA8;   /* its hairline */

  /* ---- Type -----------------------------------------------------------
     Instrument Serif for display — editorial, high contrast, unhurried.
     Inter for everything functional. */
  --glow-font-display: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  --glow-font-body:    'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --glow-h1:    clamp(3rem, 7.4vw, 5.5rem);
  --glow-h2:    clamp(2rem, 4.2vw, 3.25rem);
  --glow-h3:    clamp(1.3rem, 2vw, 1.625rem);
  --glow-lead:  clamp(1.0625rem, 1.5vw, 1.1875rem);
  --glow-body:  1.0625rem;
  --glow-small: 0.875rem;   /* 14px — the portal's workhorse */
  --glow-meta:  0.75rem;    /* 12px — genuinely secondary text */
  --glow-tag:   0.6875rem;  /* 11px — UPPERCASE eyebrows only; caps read larger */

  /* ---- Portal type ------------------------------------------------------
     ADDED 5 AUGUST 2026. Hemi, comparing the portal with SigmaSync's client
     portal: *"the multiple text sizes and positioning is still very messy."*

     He was right, and it was measurable. The overview rendered TWELVE distinct
     font sizes — 10, 11, 12, 13, 14, 15, 16, 17–19, 20, 28px — and two <h2>s
     at the same nesting level rendered at 12px and 20px. `_portal.css` carried
     fifteen hardcoded sizes with no token behind any of them, including
     `0.9375rem` used ten times as a de-facto row size that exists between
     --glow-small and --glow-body and belongs to neither.

     THE CAUSE WAS A MISSING SCALE, NOT CARELESSNESS. The tokens above are the
     PUBLIC scale: --glow-h1 tops out at 88px, which no portal page could ever
     use. So every portal component invented its own size, each one reasonable
     alone and none of them agreeing.

     Four tokens close it. Every portal component maps onto one of these plus
     --glow-body / --glow-small / --glow-meta, which takes the portal from
     twelve rendered sizes to seven.

     Named `pt-` rather than added to the scale above because the public site
     must not inherit them: a 1.25rem "card title" would be wrong on a page
     whose h2 is 52px. Two surfaces, two scales, stated once. */
  --glow-pt-h1:    1.75rem;    /* 28px — the portal page title, and the largest
                                  thing on any portal page */
  --glow-pt-card:  1.25rem;    /* 20px — EVERY serif card, tile and section
                                  title. Was four sizes within 4px of each
                                  other, which reads as a rendering fault
                                  rather than a hierarchy */
  --glow-pt-row:   0.9375rem;  /* 15px — a row title or a stated value. The
                                  size that was already doing this job ten
                                  times over without a name */
  --glow-pt-label: 0.6875rem;  /* 11px — THE uppercase eyebrow. One size, 600,
                                  0.11em. There were six variants: 10–12px,
                                  tracking 0.06–0.18em, three colours */

  /* The vertical inset on every header row — .glow-block__head,
     .glow-card__head and .glow-sec > summary. They were 1.05rem, 1.5rem and
     1.15rem: three near-identical values that stack visibly when a card sits
     inside a block, which is the normal case. */
  --glow-head-y: 1.05rem;

  /* ---- Space ---------------------------------------------------------- */
  --glow-s1:  0.5rem;
  --glow-s2:  1rem;
  --glow-s3:  1.5rem;
  --glow-s4:  2rem;
  --glow-s5:  3rem;
  --glow-s6:  4.5rem;
  --glow-s7:  7rem;
  --glow-s8:  10rem;

  --glow-section-y: clamp(4rem, 9vw, 8rem);

  /* ---- Measure --------------------------------------------------------- */
  --glow-container: 1280px;
  --glow-measure:   62ch;
  --glow-gutter:    clamp(1.25rem, 5vw, 3.5rem);

  /* ---- Form ------------------------------------------------------------
     Soft, not sharp. Cards are rounded; the page is not. */
  --glow-radius:    14px;
  --glow-radius-sm: 999px;

  /* ---- Motion ---------------------------------------------------------- */
  --glow-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --glow-dur:  380ms;
}

@media (prefers-reduced-motion: reduce) {
  :root { --glow-dur: 1ms; }
}
/* ==========================================================================
   Glow Cosmetique — base typography and layout primitives
   ========================================================================== */

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--glow-cream);
  color: var(--glow-ink-soft);
  font-family: var(--glow-font-body);
  font-size: var(--glow-body);
  line-height: 1.7;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4 {
  font-family: var(--glow-font-display);
  color: var(--glow-ink);
  font-weight: 400;
  letter-spacing: -0.015em;
  line-height: 1.06;
  margin: 0;
}

h1 { font-size: var(--glow-h1); }
h2 { font-size: var(--glow-h2); line-height: 1.1; }
h3 { font-size: var(--glow-h3); line-height: 1.25; letter-spacing: -0.005em; }

p { margin: 0 0 var(--glow-s3); max-width: var(--glow-measure); }
p:last-child { margin-bottom: 0; }

a { color: inherit; text-decoration: none; }

/* ---- Layout ------------------------------------------------------------ */

.glow-container {
  width: 100%;
  max-width: var(--glow-container);
  margin-inline: auto;
  padding-inline: var(--glow-gutter);
}

.glow-section { padding-block: var(--glow-section-y); }
.glow-section--tight { padding-block: clamp(3rem, 6vw, 5rem); }
.glow-section--line { border-top: 1px solid var(--glow-border); }

/* ---- Tag ---------------------------------------------------------------
   Small pill label. Names the section without shouting. Replaces the
   letterspaced eyebrow — softer, and it reads as a label rather than a
   heading fragment. */

.glow-tag {
  display: inline-block;
  font-family: var(--glow-font-body);
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--glow-muted);
  background: var(--glow-blush);
  border-radius: var(--glow-radius-sm);
  padding: 0.45rem 0.9rem;
  margin: 0 0 var(--glow-s4);
}

.glow-tag--onDeep {
  background: rgba(250, 247, 242, 0.1);
  color: rgba(250, 247, 242, 0.72);
}

/* ---- Lead paragraph ---------------------------------------------------- */

.glow-lead {
  font-size: var(--glow-lead);
  line-height: 1.68;
  color: var(--glow-ink-soft);
  max-width: 48ch;
}

/* ---- Button -------------------------------------------------------------
   Primary CTA. "Book a consultation" — trained interface language, decided
   30 Jul 2026 (see notes/decisions.md). Filled, calm, no shouting. */

.glow-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--glow-cream);
  background: var(--glow-burgundy);
  border: 1px solid var(--glow-burgundy);
  border-radius: 999px;
  padding: 0.9rem 1.75rem;
  white-space: nowrap;
  transition: background var(--glow-dur) var(--glow-ease),
              border-color var(--glow-dur) var(--glow-ease);
}

.glow-button:hover,
.glow-button:focus-visible {
  background: var(--glow-deep);
  border-color: var(--glow-deep);
}

.glow-button--outline {
  color: var(--glow-ink);
  background: transparent;
  border-color: var(--glow-border);
}

.glow-button--outline:hover,
.glow-button--outline:focus-visible {
  background: var(--glow-blush);
  border-color: var(--glow-border);
}

/* ---- Availability line -------------------------------------------------
   Retained as a quiet secondary CTA. No longer the only permitted form. */

.glow-availability {
  display: inline-flex;
  align-items: center;
  gap: var(--glow-s2);
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
  letter-spacing: 0.01em;
  color: var(--glow-ink);
  padding-bottom: 0.45rem;
  border-bottom: 1px solid var(--glow-ink);
  transition: border-color var(--glow-dur) var(--glow-ease),
              color var(--glow-dur) var(--glow-ease);
}

.glow-availability:hover,
.glow-availability:focus-visible {
  color: var(--glow-burgundy);
  border-color: var(--glow-burgundy);
}

.glow-availability__arrow {
  display: inline-block;
  transition: transform var(--glow-dur) var(--glow-ease);
}

.glow-availability:hover .glow-availability__arrow { transform: translateX(4px); }

.glow-availability--onDeep {
  color: var(--glow-cream);
  border-color: rgba(250, 247, 242, 0.5);
}
.glow-availability--onDeep:hover {
  color: var(--glow-cream);
  border-color: var(--glow-cream);
}

/* ---- Quiet link --------------------------------------------------------- */

.glow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--glow-small);
  color: var(--glow-burgundy);
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
  transition: border-color var(--glow-dur) var(--glow-ease);
}

.glow-link:hover { border-color: var(--glow-burgundy); }

/* ---- Focus / skip ------------------------------------------------------- */

:focus-visible { outline: 2px solid var(--glow-burgundy); outline-offset: 3px; }

.glow-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--glow-deep);
  color: var(--glow-cream);
  padding: var(--glow-s2) var(--glow-s3);
  z-index: 200;
}
.glow-skip:focus { left: 0; }

/* ---- Italic emphasis in display type ------------------------------------
   Aestetika's signature move: roman and italic mixed inside one heading.
   Instrument Serif's italic is markedly different from its roman, so the
   contrast reads as intent rather than accident. Use on one phrase only. */

.glow-em {
  font-style: italic;
  letter-spacing: 0;
}

/* ---- Section divider ----------------------------------------------------
   Oversized type as a rule. Adds scale to a page that, by doctrine, carries
   less content than a competitor's. Says nothing — which is the point. */

.glow-divider {
  overflow: hidden;
  border-top: 1px solid var(--glow-border);
  padding-block: clamp(2rem, 5vw, 4rem);
}

.glow-divider__text {
  font-family: var(--glow-font-display);
  font-size: min(8vw, 100px);
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--glow-blush);
  white-space: nowrap;
  margin: 0;
  user-select: none;
}

/* ---- Index rows ---------------------------------------------------------
   Title, description, arrow. A directory that points rather than sells. */

.glow-index { border-top: 1px solid var(--glow-border); }

.glow-index__row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--glow-s2) var(--glow-s4);
  align-items: center;
  padding-block: var(--glow-s4);
  border-bottom: 1px solid var(--glow-border);
  transition: padding-inline var(--glow-dur) var(--glow-ease);
}

/* MOBILE, fixed 6 Aug 2026. The base rule is `1fr auto` for THREE children,
   so title took column 1, description took column 2, and the arrow wrapped to
   a row of its own. On a 390px phone that squeezed the title to ~160px —
   "Peptide facial vs glass skin facial" set five lines deep in display face
   beside a half-empty description column, with a stray arrow underneath.

   Title and description belong in one column, stacked, reading top to bottom.
   The arrow spans both rows so it stays put and stops generating a third row
   of its own. */
.glow-index__title { grid-column: 1; }
.glow-index__desc  { grid-column: 1; }
.glow-index__arrow { grid-column: 2; grid-row: 1 / -1; align-self: center; }

@media (min-width: 780px) {
  .glow-index__row { grid-template-columns: 16rem 1fr auto; gap: var(--glow-s5); }
  .glow-index__row:hover { padding-inline: var(--glow-s2); }
  .glow-index__title { grid-column: 1; }
  .glow-index__desc  { grid-column: 2; }
  .glow-index__arrow { grid-column: 3; grid-row: auto; }
}

.glow-index__title {
  font-family: var(--glow-font-display);
  font-size: 1.5rem;
  color: var(--glow-ink);
  line-height: 1.2;
}

.glow-index__desc {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  margin: 0;
  max-width: 56ch;
}

.glow-index__arrow {
  color: var(--glow-burgundy);
  font-size: 1.125rem;
  transition: transform var(--glow-dur) var(--glow-ease);
}

.glow-index__row:hover .glow-index__arrow { transform: translateX(5px); }
/* ==========================================================================
   Glow Cosmetique — header and footer
   ========================================================================== */

.body-wrapper { display: flex; flex-direction: column; min-height: 100vh; }

/* ---- Header ------------------------------------------------------------ */

.glow-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--glow-cream) 90%, transparent);
  backdrop-filter: saturate(150%) blur(14px);
  border-bottom: 1px solid var(--glow-border);
}

.glow-header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--glow-s4);
  min-height: 78px;
}

.glow-wordmark {
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--glow-ink);
  white-space: nowrap;
}

.glow-nav { display: flex; align-items: center; gap: clamp(1.25rem, 2.4vw, 2.25rem); }

.glow-nav__link {
  font-size: var(--glow-small);
  letter-spacing: 0.01em;
  white-space: nowrap;
  color: var(--glow-ink-soft);
  padding-block: 0.35rem;
  border-bottom: 1px solid transparent;
  transition: color var(--glow-dur) var(--glow-ease),
              border-color var(--glow-dur) var(--glow-ease);
}

.glow-nav__link:hover,
.glow-nav__link[aria-current="page"] {
  color: var(--glow-ink);
  border-color: var(--glow-border);
}

.glow-header__cta { display: none; white-space: nowrap; }

/* Phone in the chrome — for a local clinic this converts better than any
   design element. Hidden mid-width so the nav never wraps. */
.glow-nav__phone {
  display: none;
  font-size: var(--glow-small);
  font-weight: 500;
  white-space: nowrap;
  color: var(--glow-ink);
  border-bottom: 1px solid transparent;
  transition: border-color var(--glow-dur) var(--glow-ease);
}
.glow-nav__phone:hover { border-color: var(--glow-ink); }

@media (min-width: 1140px) {
  .glow-nav__phone { display: inline-block; }
}

/* ---- Cart link + count badge --------------------------------------------
   The count is written by js/cart.js into #glow-cart-count and hidden at
   zero, so the pill only appears once something is actually in the cart. */

.glow-nav__cart {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.glow-cart-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.3em;
  padding: 0.18em 0.45em;
  font-size: var(--glow-tag);
  font-weight: 500;
  line-height: 1;
  color: var(--glow-cream);
  background: var(--glow-burgundy);
  border-radius: var(--glow-radius-sm);
}

/* display:inline-flex would defeat the hidden attribute — restate it. */
.glow-cart-count[hidden] { display: none; }

.glow-burger {
  display: inline-flex; flex-direction: column; justify-content: center;
  gap: 5px; width: 30px; height: 30px; padding: 0; border: 0;
  background: none; cursor: pointer;
}
.glow-burger span {
  display: block; height: 1px; width: 100%; background: var(--glow-ink);
  transition: transform var(--glow-dur) var(--glow-ease), opacity var(--glow-dur) var(--glow-ease);
}
.glow-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.glow-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.glow-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (min-width: 940px) {
  .glow-burger { display: none; }
  .glow-header__cta { display: inline-flex; }
}

@media (max-width: 939px) {
  .glow-nav {
    position: fixed; inset: 78px 0 auto 0;
    flex-direction: column; align-items: flex-start; gap: 0;
    background: var(--glow-cream);
    border-bottom: 1px solid var(--glow-border);
    padding: var(--glow-s2) var(--glow-gutter) var(--glow-s5);
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity var(--glow-dur) var(--glow-ease), transform var(--glow-dur) var(--glow-ease);
  }
  .glow-nav[data-open="true"] { opacity: 1; transform: none; pointer-events: auto; }
  .glow-nav__link {
    width: 100%; font-size: 1.125rem; padding-block: var(--glow-s3);
    border-bottom: 1px solid var(--glow-border);
  }
  .glow-nav .glow-availability { margin-top: var(--glow-s4); }
}

/* ---- Footer ------------------------------------------------------------
   Deep warm field. Closes the page with weight, and carries the wordmark
   at scale — the one place the brand is allowed to be large. */

.glow-footer {
  margin-top: auto;
  background: var(--glow-deep);
  color: rgba(250, 247, 242, 0.72);
  padding-top: clamp(3.5rem, 7vw, 6rem);
  overflow: hidden;
}

.glow-footer__grid {
  display: grid;
  gap: var(--glow-s5);
  grid-template-columns: 1fr;
  padding-bottom: var(--glow-s6);
}

@media (min-width: 780px) {
  .glow-footer__grid { grid-template-columns: 1.5fr 1fr 1fr; gap: var(--glow-s6); }
}

.glow-footer .glow-wordmark { color: var(--glow-cream); }

.glow-footer__heading {
  font-family: var(--glow-font-body);
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(250, 247, 242, 0.45);
  margin: 0 0 var(--glow-s3);
}

.glow-footer__list { list-style: none; margin: 0; padding: 0; }
.glow-footer__list li {
  margin-bottom: 0.7rem;
  font-size: var(--glow-small);
  color: rgba(250, 247, 242, 0.75);
}
.glow-footer__list a {
  font-size: var(--glow-small);
  color: rgba(250, 247, 242, 0.75);
  border-bottom: 1px solid transparent;
  transition: color var(--glow-dur) var(--glow-ease), border-color var(--glow-dur) var(--glow-ease);
}
.glow-footer__list a:hover { color: var(--glow-cream); border-color: rgba(250, 247, 242, 0.4); }

.glow-footer__note {
  font-size: var(--glow-small);
  color: rgba(250, 247, 242, 0.6);
  max-width: 38ch;
  margin-top: var(--glow-s3);
}

.glow-footer__base {
  display: flex; flex-wrap: wrap;
  gap: var(--glow-s2) var(--glow-s4);
  justify-content: space-between; align-items: baseline;
  padding-block: var(--glow-s3);
  border-top: 1px solid rgba(250, 247, 242, 0.14);
  font-size: 0.8125rem;
  color: rgba(250, 247, 242, 0.5);
}
.glow-footer__base a { border-bottom: 1px solid transparent; }
.glow-footer__base a:hover { border-color: rgba(250, 247, 242, 0.4); }

/* Build credit sits quieter than the legal links and takes its own line on
   narrow widths so the base row never crowds. */
.glow-footer__credit { color: rgba(250, 247, 242, 0.38); }
.glow-footer__credit a { color: rgba(250, 247, 242, 0.55); }
.glow-footer__credit a:hover { color: var(--glow-cream); }

@media (max-width: 779px) {
  .glow-footer__base { flex-direction: column; }
}

/* The large wordmark, sized to sit edge to edge inside the container.
   "Glow Cosmetique" is ~6.9em wide in Instrument Serif, so the cap keeps it
   from overflowing once the container stops growing. */
.glow-footer__mark {
  font-family: var(--glow-font-display);
  font-weight: 400;
  color: var(--glow-cream);
  font-size: min(12.6vw, 168px);
  line-height: 0.84;
  letter-spacing: -0.025em;
  padding-top: var(--glow-s4);
  padding-bottom: 0.08em;
  white-space: nowrap;
}

/* Members-only portal link. Tinted so it reads as a different KIND of thing to
   the marketing nav beside it — a way back into your own record, not another
   page to browse. Only rendered when signed in; see partials/header.html. */
.glow-nav__portal {
  background: var(--glow-blush);
  color: var(--glow-burgundy);
  border-radius: var(--glow-radius-sm);
  padding: 0.4rem 0.9rem;
}

.glow-nav__portal:hover { background: var(--glow-light); color: var(--glow-burgundy); }

/* Signed-OUT counterpart, added 6 Aug 2026. Deliberately NOT tinted like
   __portal: this is a door, not a destination. It stays a plain nav link so it
   reads as "I already have an account" and is ignored by everyone who does not
   — which is almost everyone. The previous build showed no link at all when
   signed out, on the argument that absence was honest. It was half right: it
   also made the door unfindable on a phone, where the only other one was in
   the footer. */
.glow-nav__signin { color: var(--glow-muted); }
.glow-nav__signin:hover { color: var(--glow-burgundy); }
/* ==========================================================================
   Glow Cosmetique — shared interior-page layer
   Loaded via template_css on every non-home page. Strictly on the tokens.

   Interior pages get _tokens + _base + _chrome globally, plus this file.
   _home.css is NOT loaded on interior pages — do not use its classes.
   Where a home pattern is needed here (split header, steps, FAQs), the
   rules are duplicated below and marked "keep in sync".
   ========================================================================== */

/* ---- Breadcrumb ---------------------------------------------------------
   Tiny orientation line for treatment pages: Treatments → name.
   Sits inside .glow-pagehead, above the tag. One level deep, no schema
   theatre — it's a pointer, not a nav system. */

.glow-crumb {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6rem;
  font-size: 0.8125rem;
  letter-spacing: 0.03em;
  color: var(--glow-muted);
  margin: 0 0 var(--glow-s4);
}

.glow-crumb a {
  color: var(--glow-muted);
  border-bottom: 1px solid transparent;
  transition: color var(--glow-dur) var(--glow-ease),
              border-color var(--glow-dur) var(--glow-ease);
}

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

.glow-crumb__sep { color: var(--glow-border); user-select: none; }

/* ---- Page header --------------------------------------------------------
   Quieter than the home hero: no image, one column, generous top padding.
   Grammar: [.glow-crumb] → .glow-tag → h1.glow-pagehead__title (one .glow-em
   phrase) → p.glow-lead (the 40–60 word answer block) → [__actions] → [__meta].
   The title runs a step below the home h1 so interior pages read as rooms,
   not entrances. */

.glow-pagehead {
  padding-block: clamp(3.5rem, 8vw, 6.5rem) clamp(2.5rem, 6vw, 4.5rem);
}

.glow-pagehead__title {
  font-size: clamp(2.5rem, 5.4vw, 4.25rem);
  max-width: 18ch;
  margin-bottom: var(--glow-s4);
}

.glow-pagehead__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--glow-s3) var(--glow-s4);
  margin-top: 2.25rem;
}

.glow-pagehead__meta {
  margin-top: var(--glow-s5);
  padding-top: var(--glow-s3);
  border-top: 1px solid var(--glow-border);
  max-width: 34ch;
  font-size: 0.8125rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--glow-muted);
}

/* ---- Prose --------------------------------------------------------------
   Long-form content column. Headings keep the display face but drop below
   the section scale — inside a 62ch measure the full h2 shouts. Lists get
   the burgundy dash; links are quiet and underline on hover only. */

.glow-prose { max-width: var(--glow-measure); }

.glow-prose h2 {
  font-size: clamp(1.75rem, 2.6vw, 2.25rem);
  line-height: 1.15;
  margin: var(--glow-s6) 0 var(--glow-s3);
  max-width: 26ch;
}

.glow-prose h3 {
  margin: var(--glow-s5) 0 var(--glow-s2);
  max-width: 30ch;
}

.glow-prose h2:first-child,
.glow-prose h3:first-child { margin-top: 0; }

.glow-prose p { margin: 0 0 var(--glow-s3); }

.glow-prose ul,
.glow-prose ol {
  margin: 0 0 var(--glow-s3);
  padding: 0;
  list-style: none;
  max-width: var(--glow-measure);
}

.glow-prose li {
  position: relative;
  padding-left: 1.6rem;
  margin-bottom: 0.6rem;
}

.glow-prose ul li::before {
  content: '\2014'; /* em dash */
  position: absolute;
  left: 0;
  color: var(--glow-burgundy);
}

.glow-prose ol { counter-reset: glow-prose-ol; }

.glow-prose ol li::before {
  counter-increment: glow-prose-ol;
  content: counter(glow-prose-ol);
  position: absolute;
  left: 0;
  font-family: var(--glow-font-display);
  color: var(--glow-burgundy);
}

.glow-prose a {
  color: var(--glow-burgundy);
  border-bottom: 1px solid transparent;
  transition: border-color var(--glow-dur) var(--glow-ease);
}

.glow-prose a:hover,
.glow-prose a:focus-visible { border-bottom-color: var(--glow-burgundy); }

.glow-prose strong { font-weight: 500; color: var(--glow-ink); }

.glow-prose blockquote {
  margin: var(--glow-s4) 0;
  padding-left: var(--glow-s3);
  border-left: 1px solid var(--glow-burgundy);
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  line-height: 1.4;
  color: var(--glow-ink);
}

.glow-prose blockquote p { margin: 0; }

/* ---- Prose rules and tables ---------------------------------------------
   Added 4 Aug 2026 when the first nine articles went into HubSpot. The
   markdown drafts use `---` and pipe tables, both of which were rendering
   as browser defaults on top of everything else being deliberate — and the
   table was pushing past the measure rather than scrolling inside it.

   Written to the same rules as the portal's analyte rows: hairline
   separators, no vertical lines, no zebra striping. A table on a clinical
   page is read across a row, and anything that draws the eye down a column
   is fighting that. */

.glow-prose hr {
  border: 0;
  border-top: 1px solid var(--glow-border);
  margin: var(--glow-s5) 0;
  max-width: var(--glow-measure);
}

/* The scroll container, not the table. A wide table has to scroll inside
   itself — the page body must never scroll sideways. */
.glow-tablewrap {
  max-width: var(--glow-measure);
  overflow-x: auto;
  margin: 0 0 var(--glow-s4);
  -webkit-overflow-scrolling: touch;
}

/* Reading measure is right for prose and wrong for a wide comparison table —
   /comparisons runs four columns across eleven treatments and the cap turns it
   into a column of fragments. Opt-in, so no existing table moves. */
.glow-tablewrap--wide { max-width: none; }

.glow-prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--glow-small);
  line-height: 1.5;
  /* Below this the cells wrap to one word a line and the row stops being
     readable, so it scrolls instead. */
  min-width: 30rem;
}

.glow-prose thead th {
  text-align: left;
  font-size: var(--glow-meta);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--glow-muted);
  padding: 0 var(--glow-s2) 0.6rem 0;
  border-bottom: 1px solid var(--glow-border);
}

/* An empty header cell is normal here — several tables are two-column
   comparisons where the left column needs no label. Collapse it rather than
   leaving a stub of border. */
.glow-prose thead th:empty { padding: 0; }

.glow-prose tbody td {
  padding: 0.7rem var(--glow-s2) 0.7rem 0;
  border-bottom: 1px solid var(--glow-border);
  vertical-align: top;
}

.glow-prose tbody tr:last-child td { border-bottom: 0; }
.glow-prose table th:last-child,
.glow-prose table td:last-child { padding-right: 0; }

/* First column carries the label in most of these tables. */
.glow-prose tbody td:first-child { color: var(--glow-ink); }

/* ---- Spec grid ----------------------------------------------------------
   Treatment facts on a blush field: duration, price, frequency, suits,
   doesn't suit. Markup is a <dl>:

     <dl class="glow-spec">
       <div class="glow-spec__item">
         <dt class="glow-spec__term">Price</dt>
         <dd class="glow-spec__desc">$250</dd>
       </div>
       <div class="glow-spec__item glow-spec__item--wide">
         <dt class="glow-spec__term">Suits</dt>
         <dd class="glow-spec__note">Sentence-length value.</dd>
       </div>
     </dl>

   __desc is for short facts (serif, large); __note for sentence values.
   --wide spans the full row for the sentence-length items. */

.glow-spec {
  display: grid;
  gap: var(--glow-s4);
  margin: 0;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: var(--glow-s4);
}

@media (min-width: 640px) {
  .glow-spec { grid-template-columns: repeat(2, 1fr); padding: var(--glow-s5); }
}

@media (min-width: 1000px) {
  .glow-spec { grid-template-columns: repeat(4, 1fr); }
}

.glow-spec__item { min-width: 0; }

.glow-spec__item--wide { grid-column: 1 / -1; }

.glow-spec__term {
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--glow-muted);
  margin: 0 0 0.4rem;
}

.glow-spec__desc {
  margin: 0;
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  line-height: 1.3;
  color: var(--glow-ink);
}

/* ---- Spec, PROSE variant ------------------------------------------------
   Added 6 Aug 2026, after seeing /ingredients and /concerns rendered.

   THE DIAGNOSIS IS A MISUSE, NOT A BUG. .glow-spec was built for SHORT values
   — its own doc comment shows `<dt>Price</dt><dd>$250</dd>`. The __desc is
   styled as a display-face VALUE: serif, 1.375rem, line-height 1.3. That is
   right for "$250" and wrong for a forty-word sentence, which is what the four
   new hub pages put in it.

   What it produced: eight items across four columns, one running eight lines
   deep and setting the height of the whole row, then a full-width final item
   whose measure ran past 140 characters.

   So: two columns rather than four, the display face kept but stepped down,
   and line-height opened up. Same component, same voice, built for sentences.

   Two columns is also why the counts work — 4, 6 and 8 items all give whole
   rows, where four columns left a 4/3/1 orphan on every page using it. */
.glow-spec--prose { gap: var(--glow-s5) var(--glow-s6); }

@media (min-width: 1000px) {
  .glow-spec--prose { grid-template-columns: repeat(2, 1fr); }
}

.glow-spec--prose .glow-spec__desc {
  font-size: 1.125rem;
  line-height: 1.45;
  max-width: 46ch;
}

/* A full-width item in a TWO-column grid reads as a closing summary rather
   than an orphan — but the container is ~90ch and prose is unreadable at that
   width, so the measure is capped rather than the item. */
.glow-spec--prose .glow-spec__item--wide .glow-spec__desc { max-width: 74ch; }

.glow-spec__note {
  margin: 0;
  font-size: var(--glow-small);
  line-height: 1.6;
  color: var(--glow-ink-soft);
  max-width: 62ch;
}


/* ---- Comparison table ---------------------------------------------------
   /comparisons. Added 6 Aug 2026 to override the HubSpot boilerplate.

   WHY THIS EXISTS RATHER THAN JUST USING `.glow-prose table`. The theme ships
   `css/theme-overrides.css`, which styles every bare <table> with HubSpot's
   default: a filled dark header bar and a border on every cell. That is what
   rendered — a heavy grid with centred bold row headers, in a design system
   whose every other table is hairline-separated.

   The centred row headers were a second, quieter defect: `.glow-prose thead th`
   sets text-align left, and `tbody th` had no rule at all, so it fell through
   to the browser default of centre + bold. Every treatment name was centred in
   a left-aligned table and nobody would have called it a bug — it just looked
   slightly wrong.

   Grammar follows .glow-pricetable: hairline rows, blush hover, display face
   on the number, and nothing vertical anywhere. */
.glow-comparetable {
  width: 100%;
  border-collapse: collapse;
  margin: 0;
  min-width: 44rem;
  background: none;
  border: 0;
}

.glow-comparetable th,
.glow-comparetable td {
  background: none;
  border: 0;
  border-bottom: 1px solid var(--glow-border);
}

.glow-comparetable thead th {
  font-family: var(--glow-font-body);
  font-size: var(--glow-meta);
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--glow-muted);
  text-align: left;
  padding: 0 var(--glow-s3) 0.7rem 0;
  white-space: nowrap;
}

.glow-comparetable tbody th,
.glow-comparetable tbody td {
  padding: var(--glow-s3) var(--glow-s3) var(--glow-s3) 0;
  vertical-align: top;
  transition: background var(--glow-dur) var(--glow-ease);
}

/* The fix for the centred names. Also drops the browser's bold — emphasis is
   carried by the link colour, and two emphases on one cell is one too many. */
.glow-comparetable tbody th {
  text-align: left;
  font-weight: 500;
  color: var(--glow-ink);
  width: 30%;
}

.glow-comparetable tbody tr:hover th,
.glow-comparetable tbody tr:hover td { background: var(--glow-blush); }

/* Numbers in the display face, as they are on /pricing. Nowrap because
   "By consultation" breaking mid-phrase was half the raggedness. */
.glow-comparetable__price {
  font-family: var(--glow-font-display);
  font-size: 1.25rem;
  color: var(--glow-ink);
  white-space: nowrap;
  width: 14%;
}

/* "Assessment first" wrapped onto two lines on seven of eleven rows, which is
   what made the column look broken. It is a label, so it never wraps. */
.glow-comparetable__gate {
  font-size: var(--glow-small);
  color: var(--glow-ink-soft);
  white-space: nowrap;
  width: 18%;
}

.glow-comparetable__for {
  font-size: var(--glow-small);
  line-height: 1.55;
  color: var(--glow-muted);
  max-width: 42ch;
}

/* MOBILE: STACK, DO NOT SCROLL.
   The tablewrap makes a wide table scroll inside itself, which is correct for
   a page body and wrong for the primary content of a page. On a 390px phone
   four columns means the reader has to discover a sideways scroll to reach
   "Broadly for" — and most never do. Glow's clients are on phones.

   So below 720px the table stops being a table and becomes one card per
   treatment: name, then price and booking on a line, then the description.
   The <th>/<td> semantics and the header row are untouched, so a screen
   reader and a crawler still see a table — only the visual layout changes. */
@media (max-width: 720px) {
  .glow-comparetable { min-width: 0; display: block; }
  .glow-comparetable thead { display: none; }
  .glow-comparetable tbody,
  .glow-comparetable tbody tr { display: block; }

  .glow-comparetable tbody tr {
    padding: var(--glow-s3) 0;
    border-bottom: 1px solid var(--glow-border);
  }
  .glow-comparetable tbody tr:hover th,
  .glow-comparetable tbody tr:hover td { background: none; }

  .glow-comparetable tbody th,
  .glow-comparetable tbody td {
    display: block;
    width: auto;
    border: 0;
    padding: 0;
  }

  .glow-comparetable tbody th {
    font-size: 1.0625rem;
    margin-bottom: 0.35rem;
  }

  /* Price and gate share a line — they are the two facts being compared, and
     stacking them wastes the height that stacking was meant to buy.

     ⚠ SELECTOR MUST CARRY `td`. Measured: the first version used the bare
     class and lost. `.glow-comparetable tbody td` is one class plus two
     elements (0,1,2); `.glow-comparetable__price` is one class (0,1,0). The
     block rule above won on specificity and the two sat on separate lines —
     rendering perfectly, just not as designed. Nothing errors when a CSS rule
     silently loses, which is the same shape as every other bug on this build. */
  .glow-comparetable tbody td.glow-comparetable__price {
    display: inline-block;
    font-size: 1.125rem;
    margin-right: var(--glow-s2);
  }
  .glow-comparetable tbody td.glow-comparetable__gate {
    display: inline-block;
    color: var(--glow-muted);
  }
  .glow-comparetable__gate::before { content: "· "; }

  .glow-comparetable__for {
    max-width: none;
    margin-top: 0.4rem;
  }
}

/* ---- Price table --------------------------------------------------------
   The full published list. Group heading rows carry the display face;
   item rows are hairline-separated with a blush hover; prices sit right.

     <table class="glow-pricetable">
       <tbody>
         <tr class="glow-pricetable__group"><th colspan="2" scope="colgroup">Facials</th></tr>
         <tr class="glow-pricetable__row">
           <td class="glow-pricetable__item">Glass Skin Facial
             <span class="glow-pricetable__detail">90 minutes</span></td>
           <td class="glow-pricetable__price">$250</td>
         </tr>
       </tbody>
     </table> */

.glow-pricetable {
  width: 100%;
  border-collapse: collapse;
  margin: 0;
}

.glow-pricetable__group th {
  font-family: var(--glow-font-display);
  font-size: 1.5rem;
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: -0.005em;
  color: var(--glow-ink);
  text-align: left;
  padding: var(--glow-s6) var(--glow-s3) var(--glow-s2);
  border-bottom: 1px solid var(--glow-border);
}

/* First group in the table sits flush with whatever precedes it. */
.glow-pricetable tbody:first-child > .glow-pricetable__group:first-child th {
  padding-top: 0;
}

.glow-pricetable__row td {
  padding: var(--glow-s3);
  border-bottom: 1px solid var(--glow-border);
  vertical-align: top;
  transition: background var(--glow-dur) var(--glow-ease);
}

.glow-pricetable__row:hover td { background: var(--glow-blush); }

.glow-pricetable__item { color: var(--glow-ink); }

.glow-pricetable__detail {
  display: block;
  font-size: var(--glow-small);
  color: var(--glow-muted);
  margin-top: 0.2rem;
  max-width: 52ch;
}

.glow-pricetable__price {
  font-family: var(--glow-font-display);
  font-size: 1.25rem;
  color: var(--glow-ink);
  text-align: right;
  white-space: nowrap;
}

/* ---- CTA band -----------------------------------------------------------
   End-of-page close. Light variant sits on blush; --deep takes the deep
   field for pages that need the candour weight at the end. One button,
   stated once — heading + .glow-button, optional short __desc. */

.glow-cta-band {
  display: grid;
  gap: var(--glow-s4);
  align-items: center;
  justify-items: start;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: clamp(2.5rem, 6vw, 4.5rem) clamp(1.5rem, 4vw, 4rem);
}

@media (min-width: 860px) {
  .glow-cta-band { grid-template-columns: 1fr auto; gap: var(--glow-s5); }
}

.glow-cta-band__title {
  font-size: clamp(1.75rem, 3.2vw, 2.5rem);
  line-height: 1.12;
  max-width: 22ch;
  margin: 0 0 var(--glow-s2);
}

.glow-cta-band__title:last-child { margin-bottom: 0; }

.glow-cta-band__desc {
  font-size: var(--glow-body);
  color: var(--glow-ink-soft);
  max-width: 48ch;
  margin: 0;
}

.glow-cta-band--deep {
  background: var(--glow-deep);
  color: rgba(250, 247, 242, 0.72);
}

.glow-cta-band--deep .glow-cta-band__title { color: var(--glow-cream); }

.glow-cta-band--deep .glow-cta-band__desc { color: rgba(250, 247, 242, 0.62); }

/* On the deep field the button's hover state would sink into the band —
   invert it instead. */
.glow-cta-band--deep .glow-button:hover,
.glow-cta-band--deep .glow-button:focus-visible {
  background: var(--glow-cream);
  border-color: var(--glow-cream);
  color: var(--glow-ink);
}

/* ==========================================================================
   Duplicated patterns — these also exist in _home.css. Only one of the two
   files is ever loaded on a page, so there is no cascade conflict, but any
   change must be made in both places.
   ========================================================================== */

/* ---- Split header — duplicated from _home.css — keep in sync ---- */

.glow-split { display: grid; gap: var(--glow-s5); }

@media (min-width: 920px) {
  .glow-split {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: var(--glow-s7);
    align-items: start;
  }
}

/* ---- Steps — duplicated from _home.css — keep in sync ---- */

.glow-steps {
  display: grid;
  gap: 0.5rem;
  margin-top: var(--glow-s6);
}

.glow-step {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  gap: var(--glow-s2) var(--glow-s3);
  align-items: baseline;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: var(--glow-s4);
}

@media (min-width: 780px) {
  .glow-step {
    grid-template-columns: 3.5rem 13rem 1fr;
    gap: var(--glow-s4);
    padding: var(--glow-s4) var(--glow-s5);
    align-items: center;
  }
}

.glow-step__num {
  font-family: var(--glow-font-display);
  font-size: 1.0625rem;
  color: var(--glow-burgundy);
}

.glow-step__name {
  font-family: var(--glow-font-display);
  font-size: 1.5rem;
  color: var(--glow-ink);
  line-height: 1.2;
}

.glow-step__desc {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  margin: 0;
  max-width: 54ch;
}

@media (max-width: 779px) {
  .glow-step__desc { grid-column: 2; }
}

/* ---- FAQs — duplicated from _home.css — keep in sync ---- */

.glow-faqs {
  margin-top: var(--glow-s6);
  border-top: 1px solid var(--glow-border);
}

.glow-faq { border-bottom: 1px solid var(--glow-border); }

.glow-faq__q {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--glow-s4);
  cursor: pointer;
  list-style: none;
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  line-height: 1.3;
  color: var(--glow-ink);
  padding-block: var(--glow-s4);
}

.glow-faq__q::-webkit-details-marker { display: none; }

.glow-faq__q::after {
  content: '+';
  flex: none;
  font-family: var(--glow-font-body);
  font-size: 1.25rem;
  color: var(--glow-burgundy);
  transition: transform var(--glow-dur) var(--glow-ease);
}

.glow-faq[open] .glow-faq__q::after { transform: rotate(45deg); }

.glow-faq__a {
  font-size: var(--glow-small);
  color: var(--glow-ink-soft);
  max-width: 62ch;
  margin: 0;
  padding: 0 0 var(--glow-s4);
}


/* ==========================================================================
   ARTICLE — the three blog streams
   templates/blog-post.html · templates/blog-index.html
   ========================================================================== */

/* Byline. Small, but it is the thing that separates this from the anonymous
   content the rest of the industry publishes, so it is ink rather than muted —
   the author's name is a claim, not metadata. */
.glow-article__byline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  font-size: var(--glow-small);
  color: var(--glow-muted);
  margin: var(--glow-s3) 0 0;
  max-width: none;
}

.glow-article__author { font-weight: 500; color: var(--glow-ink); }

.glow-article__body { max-width: 34rem; margin-inline: auto; }

/* ── THE ARTICLE COLUMN IS CENTRED. Fixed 5 Aug 2026, reported by Hemi.
   ─────────────────────────────────────────────────────────────────────────
   Measured on /notes/faces-change-structurally-not-just-superficially at
   1440: the article body was 544px pinned to the LEFT of a 1280px container,
   leaving 760px of empty page beside every paragraph.

   THE CAUSE IS INHERITANCE, NOT AN OVERSIGHT IN THIS FILE. Every other
   template opens with the same measure-width, left-aligned .glow-pagehead and
   then follows it with a full-width .glow-split — verified on /approach, where
   the splits run the whole 1168px. The header reads as left-aligned because
   something wide sits under it.

   Long-form is the one page type where the measure-width column IS the whole
   page. It took the header pattern and never got the wide content that
   justifies it, so the layout the rest of the site uses correctly becomes a
   column of text against a void.

   Only the header and the body narrow. The related-posts index and the CTA
   band below them keep the full container — they are built to span it, and a
   full-width band is the correct punctuation at the end of a narrow read.

   NOT a fix for the table, which was the other half of the report. The table
   is inside .glow-tablewrap with overflow-x:auto and it behaves: at 1440 it
   fits at 544px with no clipping. Below ~700px it scrolls, which is correct —
   macOS hides the scrollbar until it is touched, so a screenshot of a scrolling
   table is indistinguishable from a clipped one. */
.glow-article > header > .glow-container,
.glow-article > .glow-section--tight > .glow-container {
  max-width: calc(36rem + var(--glow-gutter) * 2);
}

/* Every H2 in a post is an answer-block heading (SEO-AEO-GEO §3) and gets an id
   so it is individually linkable. The anchor is invisible until the heading is
   hovered or focused — present for anyone who wants to quote a specific answer,
   absent for everyone reading. */
.glow-article__body h2 { position: relative; scroll-margin-top: var(--glow-s4); }

.glow-article__body h2 .glow-anchor {
  position: absolute;
  left: -1.25rem;
  opacity: 0;
  color: var(--glow-muted);
  text-decoration: none;
  transition: opacity var(--glow-dur) var(--glow-ease);
}

.glow-article__body h2:hover .glow-anchor,
.glow-article__body h2 .glow-anchor:focus-visible { opacity: 1; }

@media (max-width: 720px) { .glow-article__body h2 .glow-anchor { display: none; } }

.glow-article__tags {
  margin: var(--glow-s5) 0 0;
  font-size: var(--glow-small);
  color: var(--glow-muted);
  max-width: none;
}

.glow-article__tags a { color: var(--glow-muted); border-bottom: 1px solid transparent; }
.glow-article__tags a:hover { color: var(--glow-ink); border-color: var(--glow-border); }

/* The standing disclosure. Quiet, but on every article — the alternative is a
   reader taking a blog post as personal advice. */
.glow-article__note {
  margin: var(--glow-s4) 0 0;
  padding-top: var(--glow-s3);
  border-top: 1px solid var(--glow-border);
  font-size: var(--glow-small);
  color: var(--glow-muted);
  max-width: 34rem;
}

.glow-article__pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--glow-s3);
  margin-top: var(--glow-s5);
  padding-top: var(--glow-s3);
  border-top: 1px solid var(--glow-border);
}

.glow-article__pager-pos {
  font-size: var(--glow-small);
  color: var(--glow-muted);
}
/* ==========================================================================
   Glow Cosmetique — home page
   ========================================================================== */

/* ---- Hero --------------------------------------------------------------
   Asymmetric. Statement left, image right bleeding to the viewport edge,
   with a tinted field offset behind it. Composition rather than decoration. */

.glow-hero {
  padding-block: clamp(3rem, 7vw, 6rem) clamp(4rem, 9vw, 7rem);
  overflow: hidden;
}

.glow-hero__grid { display: grid; gap: var(--glow-s6); }

@media (min-width: 980px) {
  .glow-hero__grid {
    grid-template-columns: minmax(0, 0.98fr) minmax(0, 1fr);
    gap: var(--glow-s7);
    align-items: center;
  }
}

.glow-hero__figure { position: relative; order: -1; }

@media (min-width: 980px) {
  .glow-hero__figure { order: 0; margin-right: calc(50% - 50vw); }
}

.glow-hero__figure::before {
  content: '';
  position: absolute;
  left: -2rem; bottom: -2rem;
  width: 55%; height: 70%;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  z-index: 0;
}

.glow-hero__figure img {
  position: relative; z-index: 1;
  width: 100%;
  height: clamp(23rem, 58vh, 38rem);
  object-fit: cover;
  object-position: 32% 18%;
  border-radius: var(--glow-radius) 0 0 var(--glow-radius);
}

@media (max-width: 979px) {
  .glow-hero__figure img { border-radius: var(--glow-radius); }
}

.glow-hero__title { max-width: 19ch; margin-bottom: var(--glow-s4); }

.glow-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--glow-s3) var(--glow-s4);
  margin-top: 2.25rem;
}

.glow-hero__meta {
  margin-top: var(--glow-s5);
  padding-top: var(--glow-s3);
  border-top: 1px solid var(--glow-border);
  max-width: 34ch;
  font-size: 0.8125rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--glow-muted);
}

/* ---- Split header ------------------------------------------------------- */

.glow-split { display: grid; gap: var(--glow-s5); }

@media (min-width: 920px) {
  .glow-split {
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    gap: var(--glow-s7);
    align-items: start;
  }
}

/* ---- Problem cards ------------------------------------------------------
   The empathy beat. The client's own words as the headings. */

.glow-problems {
  display: grid;
  gap: 0.5rem;
  margin-top: var(--glow-s6);
}

@media (min-width: 860px) {
  .glow-problems { grid-template-columns: repeat(3, 1fr); }
}

.glow-problem {
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: var(--glow-s5) var(--glow-s4);
}

.glow-problem__title {
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  line-height: 1.25;
  color: var(--glow-ink);
  margin: 0 0 var(--glow-s2);
}

.glow-problem__desc {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  margin: 0;
}

/* ---- FAQ preview --------------------------------------------------------
   Native details/summary. Answers follow the 40–60 word answer-block
   pattern so they read the same here as in a snippet. */

.glow-faqs {
  margin-top: var(--glow-s6);
  border-top: 1px solid var(--glow-border);
}

.glow-faq { border-bottom: 1px solid var(--glow-border); }

.glow-faq__q {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--glow-s4);
  cursor: pointer;
  list-style: none;
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  line-height: 1.3;
  color: var(--glow-ink);
  padding-block: var(--glow-s4);
}

.glow-faq__q::-webkit-details-marker { display: none; }

.glow-faq__q::after {
  content: '+';
  flex: none;
  font-family: var(--glow-font-body);
  font-size: 1.25rem;
  color: var(--glow-burgundy);
  transition: transform var(--glow-dur) var(--glow-ease);
}

.glow-faq[open] .glow-faq__q::after { transform: rotate(45deg); }

.glow-faq__a {
  font-size: var(--glow-small);
  color: var(--glow-ink-soft);
  max-width: 62ch;
  margin: 0;
  padding: 0 0 var(--glow-s4);
}

/* ---- Steps -------------------------------------------------------------
   Soft tinted rows. A sequence, not a funnel — no progress state, no
   completion, nothing to keep up with. */

.glow-steps {
  display: grid;
  gap: 0.5rem;
  margin-top: var(--glow-s6);
}

.glow-step {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  gap: var(--glow-s2) var(--glow-s3);
  align-items: baseline;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: var(--glow-s4);
}

@media (min-width: 780px) {
  .glow-step {
    grid-template-columns: 3.5rem 13rem 1fr;
    gap: var(--glow-s4);
    padding: var(--glow-s4) var(--glow-s5);
    align-items: center;
  }
}

.glow-step__num {
  font-family: var(--glow-font-display);
  font-size: 1.0625rem;
  color: var(--glow-burgundy);
}

.glow-step__name {
  font-family: var(--glow-font-display);
  font-size: 1.5rem;
  color: var(--glow-ink);
  line-height: 1.2;
}

.glow-step__desc {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  margin: 0;
  max-width: 54ch;
}

@media (max-width: 779px) {
  .glow-step__desc { grid-column: 2; }
}

/* ---- Limits ------------------------------------------------------------
   Deep field. Doctrine: authority comes from limits, so this gets the
   strongest visual weight on the page. */

.glow-limits { background: var(--glow-deep); color: rgba(250, 247, 242, 0.72); }
.glow-limits h2 { color: var(--glow-cream); }

.glow-limits__grid { display: grid; gap: 0.5rem; margin-top: var(--glow-s6); }

@media (min-width: 780px) {
  .glow-limits__grid { grid-template-columns: repeat(2, 1fr); }
}

.glow-limit {
  background: rgba(250, 247, 242, 0.055);
  border-radius: var(--glow-radius);
  padding: var(--glow-s4);
}

@media (min-width: 780px) { .glow-limit { padding: var(--glow-s5); } }

.glow-limit__title {
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  color: var(--glow-cream);
  margin: 0 0 var(--glow-s2);
  line-height: 1.25;
}

.glow-limit__desc {
  font-size: var(--glow-small);
  color: rgba(250, 247, 242, 0.62);
  margin: 0;
  max-width: 44ch;
}

/* ---- Treatments --------------------------------------------------------- */

.glow-treatments { margin-top: var(--glow-s6); display: grid; gap: 0.5rem; }

.glow-treatment {
  display: flex; flex-wrap: wrap;
  justify-content: space-between; align-items: baseline;
  gap: var(--glow-s2);
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: var(--glow-s3) var(--glow-s4);
  transition: background var(--glow-dur) var(--glow-ease);
}

@media (min-width: 780px) { .glow-treatment { padding: var(--glow-s3) var(--glow-s5); } }

.glow-treatment:hover { background: var(--glow-light); }

.glow-treatment__name {
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  color: var(--glow-ink);
}

.glow-treatment__meta {
  font-size: var(--glow-small);
  color: var(--glow-muted);
}

/* ---- Close -------------------------------------------------------------- */

.glow-close__title { max-width: 18ch; margin-bottom: var(--glow-s4); }
/* ==========================================================================
   Glow Cosmetique — shop
   Product grid, filter chips, product detail. Strictly on the tokens:
   blush fields, hairlines, serif display, pill controls. No badges, no
   sale flashes, no urgency furniture — the shelf is quiet by design.
   ========================================================================== */

/* ---- Filter chips -------------------------------------------------------
   Anchor-based for v1: brand chips link to /shop/brands/<brand>, category
   chips jump to in-page anchors. No JS. */

.glow-shop-filter {
  display: grid;
  gap: var(--glow-s2);
  margin-top: var(--glow-s6);
  padding-top: var(--glow-s4);
  border-top: 1px solid var(--glow-border);
}

.glow-chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.glow-chip-row__label {
  flex: none;
  min-width: 5.5rem;
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--glow-muted);
}

.glow-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4rem;
  font-family: var(--glow-font-body);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--glow-ink-soft);
  background: transparent;
  border: 1px solid var(--glow-border);
  border-radius: var(--glow-radius-sm);
  padding: 0.4rem 0.95rem;
  white-space: nowrap;
  transition: background var(--glow-dur) var(--glow-ease),
              border-color var(--glow-dur) var(--glow-ease),
              color var(--glow-dur) var(--glow-ease);
}

.glow-chip:hover,
.glow-chip:focus-visible {
  background: var(--glow-blush);
}

.glow-chip--active {
  color: var(--glow-cream);
  background: var(--glow-deep);
  border-color: var(--glow-deep);
}

.glow-chip--active:hover { background: var(--glow-deep); }

.glow-chip__count {
  font-size: var(--glow-tag);
  font-weight: 400;
  color: var(--glow-muted);
}

.glow-chip--active .glow-chip__count { color: rgba(250, 247, 242, 0.6); }

/* ---- Category sections -------------------------------------------------- */

.glow-shop-cat { scroll-margin-top: 7rem; }
.glow-shop-cat + .glow-shop-cat { margin-top: var(--glow-s7); }

.glow-shop-cat__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--glow-s3);
  border-top: 1px solid var(--glow-border);
  padding-top: var(--glow-s3);
  margin-bottom: var(--glow-s4);
}

.glow-shop-cat__count {
  font-size: var(--glow-small);
  color: var(--glow-muted);
}

/* ---- Product grid -------------------------------------------------------
   2-up mobile, 3-up tablet, 4-up desktop. Tight column gap echoes the
   tiled blush rows used elsewhere on the site. */

.glow-products {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--glow-s5) 0.5rem;
}

@media (min-width: 720px)  { .glow-products { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1080px) { .glow-products { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* Related products on the detail page cap at 4-up too; same grid. */
.glow-products--related { margin-top: var(--glow-s6); }

/* ---- Product card -------------------------------------------------------
   Image on a blush field. Multiply blend folds white studio backgrounds
   into the tint so shots read as cut-outs without re-editing. */

.glow-product {
  display: flex;
  flex-direction: column;
}

.glow-product__link { display: block; }

.glow-product__media {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 5;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: 11%;
  overflow: hidden;
}

.glow-product__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
  transition: transform var(--glow-dur) var(--glow-ease);
}

.glow-product__link:hover .glow-product__media img,
.glow-product__link:focus-visible .glow-product__media img {
  transform: scale(1.04);
}

.glow-product__brand {
  display: block;
  margin-top: var(--glow-s3);
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--glow-muted);
}

.glow-product__title {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--glow-font-display);
  font-size: 1.25rem;
  line-height: 1.25;
  color: var(--glow-ink);
}

.glow-product__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--glow-s2);
  margin-top: auto;
  padding-top: var(--glow-s2);
}

.glow-product__price {
  font-size: var(--glow-small);
  color: var(--glow-ink);
}

/* ---- Add to cart --------------------------------------------------------
   .glow-add is the contract with the cart script (built separately): it
   binds to this class and reads the data-* attributes. Quiet outline pill
   on cards; --solid variant matches .glow-button on the detail page. */

.glow-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--glow-font-body);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--glow-burgundy);
  background: transparent;
  border: 1px solid var(--glow-border);
  border-radius: 999px;
  padding: 0.45rem 1rem;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--glow-dur) var(--glow-ease),
              border-color var(--glow-dur) var(--glow-ease),
              color var(--glow-dur) var(--glow-ease);
}

.glow-add:hover,
.glow-add:focus-visible {
  color: var(--glow-cream);
  background: var(--glow-burgundy);
  border-color: var(--glow-burgundy);
}

.glow-add--solid {
  color: var(--glow-cream);
  background: var(--glow-burgundy);
  border-color: var(--glow-burgundy);
  font-size: var(--glow-small);
  padding: 0.9rem 1.75rem;
}

.glow-add--solid:hover,
.glow-add--solid:focus-visible {
  background: var(--glow-deep);
  border-color: var(--glow-deep);
}

/* Brief confirm state — js/cart.js applies this for a moment after an add.
   Sage is the "used rarely" secondary accent; a quiet yes, not a celebration. */
.glow-add--added,
.glow-add--added:hover,
.glow-add--added:focus-visible {
  color: var(--glow-cream);
  background: var(--glow-sage);
  border-color: var(--glow-sage);
}

/* ---- Product detail ------------------------------------------------------ */

.glow-pdp { padding-block: clamp(2.5rem, 6vw, 5rem) var(--glow-section-y); }

.glow-pdp__crumb { margin-bottom: var(--glow-s4); }

.glow-pdp__grid {
  display: grid;
  gap: var(--glow-s5);
}

@media (min-width: 980px) {
  .glow-pdp__grid {
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
    gap: var(--glow-s7);
    align-items: start;
  }
  .glow-pdp__gallery { position: sticky; top: 7rem; }
}

.glow-pdp__stage {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: 9%;
  margin: 0;
  overflow: hidden;
}

.glow-pdp__stage img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.glow-pdp__thumbs {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.glow-pdp__thumb {
  display: grid;
  place-items: center;
  width: 5rem;
  aspect-ratio: 1 / 1;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: 0.6rem;
  overflow: hidden;
}

.glow-pdp__thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.glow-pdp__title {
  max-width: 16ch;
  margin-top: 0;
}

.glow-pdp__price {
  display: flex;
  align-items: baseline;
  gap: var(--glow-s2);
  font-family: var(--glow-font-display);
  font-size: 1.5rem;
  color: var(--glow-ink);
  margin: var(--glow-s2) 0 0;
}

.glow-pdp__size {
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
  color: var(--glow-muted);
}

.glow-pdp__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--glow-s3);
  margin-top: var(--glow-s4);
}

.glow-pdp__desc {
  margin-top: var(--glow-s5);
  padding-top: var(--glow-s4);
  border-top: 1px solid var(--glow-border);
}

.glow-pdp__desc p { max-width: 52ch; }

.glow-pdp__note {
  font-size: var(--glow-small);
  color: var(--glow-muted);
}

/* Cross-link to consultation. A pointer, not a pitch. */
.glow-pdp__consult {
  margin-top: var(--glow-s5);
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: var(--glow-s4);
}

.glow-pdp__consult-title {
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  line-height: 1.3;
  color: var(--glow-ink);
  max-width: 26ch;
  margin: 0 0 var(--glow-s2);
}
/* ==========================================================================
   Glow Cosmetique — cart and checkout
   Shells only: js/cart.js renders the state into #glow-cart-root and
   #glow-checkout-root. Same restraint as the shop — hairlines, blush media
   fields, no urgency furniture. The cart states what is in it and what it
   costs; nothing else.
   ========================================================================== */

.glow-cart-heading {
  font-size: var(--glow-h2);
  margin-bottom: clamp(2rem, 5vw, 3.5rem);
}

/* ---- Line items --------------------------------------------------------- */

.glow-cart__lines {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--glow-border);
}

.glow-cart-line {
  display: grid;
  grid-template-columns: clamp(4.25rem, 16vw, 5.5rem) minmax(0, 1fr) auto;
  gap: var(--glow-s3);
  align-items: center;
  padding-block: var(--glow-s3);
  border-bottom: 1px solid var(--glow-border);
}

.glow-cart-line__media {
  display: grid;
  place-items: center;
  aspect-ratio: 1 / 1;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: 0.6rem;
  overflow: hidden;
}

.glow-cart-line__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  mix-blend-mode: multiply;
}

.glow-cart-line__title {
  display: inline-block;
  font-family: var(--glow-font-display);
  font-size: 1.25rem;
  line-height: 1.25;
  color: var(--glow-ink);
  transition: color var(--glow-dur) var(--glow-ease);
}

.glow-cart-line__title:hover { color: var(--glow-burgundy); }

.glow-cart-line__unit {
  display: block;
  margin-top: 0.2rem;
  font-size: var(--glow-small);
  color: var(--glow-muted);
}

.glow-cart-line__controls {
  display: flex;
  align-items: center;
  gap: var(--glow-s3);
  margin-top: var(--glow-s2);
}

.glow-cart-line__total {
  font-size: var(--glow-body);
  color: var(--glow-ink);
  text-align: right;
  white-space: nowrap;
}

/* ---- Quantity stepper ---------------------------------------------------- */

.glow-qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--glow-border);
  border-radius: var(--glow-radius-sm);
  overflow: hidden;
}

.glow-qty__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
  color: var(--glow-burgundy);
  cursor: pointer;
  transition: background var(--glow-dur) var(--glow-ease);
}

.glow-qty__btn:hover:not(:disabled),
.glow-qty__btn:focus-visible:not(:disabled) { background: var(--glow-blush); }

.glow-qty__btn:disabled { color: var(--glow-border); cursor: default; }

.glow-qty__num {
  min-width: 1.8rem;
  text-align: center;
  font-size: var(--glow-small);
  color: var(--glow-ink);
}

.glow-cart-line__remove {
  padding: 0;
  border: 0;
  background: none;
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
  color: var(--glow-muted);
  cursor: pointer;
  border-bottom: 1px solid transparent;
  transition: color var(--glow-dur) var(--glow-ease),
              border-color var(--glow-dur) var(--glow-ease);
}

.glow-cart-line__remove:hover,
.glow-cart-line__remove:focus-visible {
  color: var(--glow-burgundy);
  border-color: var(--glow-burgundy);
}

/* ---- Cart foot ----------------------------------------------------------- */

.glow-cart__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--glow-s3) var(--glow-s4);
  margin-top: var(--glow-s4);
}

.glow-cart__subtotal {
  display: flex;
  align-items: baseline;
  gap: var(--glow-s2);
}

.glow-cart__subtotal-label {
  font-size: var(--glow-small);
  color: var(--glow-muted);
}

.glow-cart__subtotal-amount {
  font-family: var(--glow-font-display);
  font-size: 1.75rem;
  color: var(--glow-ink);
}

/* ---- Empty state and pricing note ---------------------------------------- */

.glow-cart-empty {
  border-top: 1px solid var(--glow-border);
  padding-top: var(--glow-s4);
}

.glow-cart-empty__line {
  font-family: var(--glow-font-display);
  font-size: var(--glow-h3);
  color: var(--glow-ink);
  margin-bottom: var(--glow-s2);
}

.glow-cart-note {
  margin-top: var(--glow-s5);
  font-size: var(--glow-small);
  color: var(--glow-muted);
  max-width: 52ch;
}

/* ---- Checkout summary ---------------------------------------------------- */

.glow-summary { max-width: 40rem; }

.glow-summary__lines {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--glow-border);
}

.glow-summary__line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--glow-s3);
  padding-block: var(--glow-s2);
  border-bottom: 1px solid var(--glow-border);
}

.glow-summary__qty {
  font-size: var(--glow-small);
  color: var(--glow-muted);
}

.glow-summary__amount {
  color: var(--glow-ink);
  white-space: nowrap;
}

.glow-summary__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--glow-s3);
  padding-block: var(--glow-s3);
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  color: var(--glow-ink);
}

.glow-summary__edit { margin-top: var(--glow-s2); }

/* ---- Checkout pending note ------------------------------------------------
   Builder note, deliberately visible: payment capture is pending the AU
   payments decision (notes/decisions.md, "Open"). Remove this block when the
   payment step is real. */

.glow-checkout-pending {
  margin-top: var(--glow-s5);
  max-width: 40rem;
  background: var(--glow-blush);
  border-radius: var(--glow-radius);
  padding: var(--glow-s4);
}

.glow-checkout-pending__label {
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--glow-muted);
  margin: 0 0 var(--glow-s2);
}

.glow-checkout-pending__body {
  font-size: var(--glow-small);
  color: var(--glow-ink-soft);
  margin: 0;
  max-width: 52ch;
}
/* ==========================================================================
   Glow Cosmetique — portal and auth screens
   ==========================================================================

   Two surfaces, one vocabulary:
     · Auth screens  — the four membership templates. Deep field, centred card.
     · Portal shell  — rail + top bar + content, behind the login.

   Structural discipline is borrowed from the Sigma Sync portal; the visual
   language is Glow's own. Specifically borrowed, because they are the details
   that separate a professional portal from a stock one:

     · The rail's logo well and the top bar are BOTH 56px, so their bottom
       borders form one unbroken line across the viewport. Do not change one
       without the other.
     · Elevation is a single 1px border. No shadows on content, ever.
     · The card's outer border is one step darker than the rules inside it
       (--glow-border outside, --glow-light within), so nested lists never
       compete with the card edge.
     · Active nav is a tint fill plus accent text — no accent bar, no weight
       change, no bold. Weight stays constant in all three states.

   Deliberately NOT borrowed: progress bars, percentages, streaks, unread
   counters. A clinical record is not a productivity app. See _portal.css
   "States" for what replaces them.

   Everything is .glow- prefixed and descendant-scoped, because HubSpot injects
   its settings stylesheet inline AFTER main.css and targets bare h1/a/p/button.
   ========================================================================== */


/* ==========================================================================
   AUTH SCREENS
   Contract: templates/partials/auth-shell.html
   ========================================================================== */

.glow-auth {
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--glow-deep);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--glow-s4);
  padding: var(--glow-s5) var(--glow-gutter);
}

.glow-auth__card {
  width: 100%;
  max-width: 27rem;
  background: var(--glow-cream);
  border-radius: var(--glow-radius);
  padding: clamp(2rem, 5vw, 3rem) clamp(1.5rem, 4vw, 2.5rem);
}

/* THE LOCKUP, AND THE ONE PLACE IT FITS.
   Hemi supplied Glow-Logo.webp on 5 Aug — 496x163, ink on transparent, plus a
   cream knockout. Ink extents measured rather than eyeballed:

       GLOW          rows 0–116   (72% of the height)
       gap           rows 117–148
       COSMETIQUE    rows 149–162 (8.6% of the height)

   A letterspaced small-caps line needs ~8px to read, so the lockup needs
   8 / 0.086 = ~93px of TOTAL height before its second line is legible. That is
   why it goes here and not in the rail: the rail well is 56px, which would put
   COSMETIQUE at 4.8px, and a wordmark with an illegible second line reads as a
   printing fault. The rail keeps its one-line Instrument Serif text mark, which
   is the right answer at that size rather than a stand-in.

   280px wide → 92px tall → COSMETIQUE at ~7.9px. The card is 27rem with up to
   2.5rem of padding, so ~352px of content width: it fits with air either side.

   The artwork is cropped hard to the top edge — row 0 carries ink — so it cannot
   be optically centred without space added here. */
.glow-auth__mark {
  display: block;
  width: min(17.5rem, 80%);
  height: auto;
  margin: 0 0 var(--glow-s5);
}

/* Fallback for anywhere the asset is absent. Also what the four membership
   templates rendered until 5 Aug, and still a legitimate identity. */
.glow-auth__mark--text {
  width: auto;
  font-family: var(--glow-font-display);
  font-size: 1.375rem;
  letter-spacing: 0.02em;
  color: var(--glow-ink);
}

.glow-auth__title {
  font-family: var(--glow-font-display);
  font-size: 2rem;
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: var(--glow-ink);
  margin: 0 0 var(--glow-s2);
}

.glow-auth__intro {
  font-size: var(--glow-small);
  line-height: 1.6;
  color: var(--glow-muted);
  max-width: none;
  margin: 0 0 var(--glow-s4);
}

.glow-auth__foot {
  margin: var(--glow-s4) 0 0;
  padding-top: var(--glow-s3);
  border-top: 1px solid var(--glow-border);
  font-size: var(--glow-small);
  color: var(--glow-muted);
  max-width: none;
}

.glow-auth__foot a { color: var(--glow-burgundy); border-bottom: 1px solid transparent; }
.glow-auth__foot a:hover { border-color: var(--glow-burgundy); }

.glow-auth__base {
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(250, 247, 242, 0.4);
  margin: 0;
  max-width: none;
  text-align: center;
}

/* ---- The HubSpot form -----------------------------------------------------
   <span id="hs_cos_wrapper_" class="hs_cos_wrapper hs_cos_wrapper_widget hs_cos_wrapper_type_member_login" style="" data-hs-cos-general-type="widget" data-hs-cos-type="member_login" ><div class="hs-form-field">
  <ul class="no-list hs-error-msgs" style="text-align:center">
    <li>
      <label class="hs-membership-global-error hs-error-msg"></label>
    </li>
  </ul>
</div>
<form method="post" action="/_hcms/mem/login?portalId=441758719&templateId=359873765831&templatePath=Glow+Cosmetique%2Fcss%2Fmain.css&redirect_url=/" id="hs-membership-form" onsubmit="onFormSubmit()" data-hs-do-not-collect="">
  <input name="csrf_token" type="hidden" value=""/>
  <input name="redirect_url" type="hidden"value="/"/>
  <input id="hs-membership-form-hubspotutk" name="hubspotutk" type="hidden" />

  <div class="hs-form-field">
    <label class="hs-login-widget-email-label" for="hs-login-widget-email">Email*</label>
    <input class="hs-input" name="email"type="text"placeholder="Email"id="hs-login-widget-email"value=""/>
  </div>


  <div class="hs-form-field">
    <label class="hs-login-widget-password-label"for="hs-login-widget-password">Password*</label>
    <a class="hs-login-widget-show-password"href="javascript:show_password('hs-login-widget-password');">Show password</a>
    <input class="hs-input" name="password"type="password"placeholder="Password"id="hs-login-widget-password"/>
  </div>

  <div class="hs-form-field">
    <input class="hs-input" name="remember_me"type="checkbox"id="hs-login-widget-remember"value="true"checked>
    <label for="hs-login-widget-remember">Remember Me</label>
  </div>
  <div>
    <a id="hs_login_reset"href="/_hcms/mem/reset/request">Forgot your password?</a>
  </div>

  <input type="hidden" name="bot_challenger_token" value=""/>
<script>
(function() {
  var el = document.currentScript;
  while (el.previousElementSibling && el.previousElementSibling.tagName !== 'INPUT') {
    el = el.previousElementSibling;
  }
  var input = el.previousElementSibling;
  var iframe = document.createElement('iframe');
  iframe.style.cssText = 'display:none';
  iframe.src = '/_hcms/mem/bot-challenger-token?action=' + encodeURIComponent('login');
  document.body.appendChild(iframe);
  function onMessage(e) {
    if (e.source !== iframe.contentWindow) return;
    if (e.origin !== window.location.origin) return;
    if (!e.data || e.data.type !== 'bot-challenger-token') return;
    input.value = e.data.token;
    window.removeEventListener('message', onMessage);
    document.body.removeChild(iframe);
  }
  window.addEventListener('message', onMessage);
})();
</script>

  
  <div class="hs-membership-loader hs_submit hs-submit">
    <div class="actions">
      <input type="submit" class="hs-button primary large" value="Login"/>
    </div>
  </div>
</form>

<span class="form-separator">or</span>
<form method="post" action="/_hcms/mem/login/passwordless-auth/request?portalId=441758719" id="hs-membership-passwordless-auth-form" onsubmit="onFormSubmit()" data-hs-do-not-collect="">
  <input name="redirect_url" type="hidden"value="/"/>
  <div>
    <p>Try going password-less. Get a link sent to your email that'll sign you in.</p>
  </div>
  <div class="hs-form-field">
    <label class="hs-login-widget-email-label" for="hs-login-widget-email">Email*</label>
    <input class="hs-input" name="email"type="text"placeholder="Email"id="hs-login-widget-email"value=""/>
  </div>

  <div class="hs-form-field">
    <input class="hs-input" name="explicit_consent" type="checkbox" id="hs-passwordless-auth-explicit-consent" value="true">
    <label id="hs-passwordless-auth-checkbox-consent" for="hs-passwordless-auth-explicit-consent">I agree to allow Glow Cosmetique to store and process my personal data.</label>
  </div>

  <input type="hidden" name="bot_challenger_token" value=""/>
<script>
(function() {
  var el = document.currentScript;
  while (el.previousElementSibling && el.previousElementSibling.tagName !== 'INPUT') {
    el = el.previousElementSibling;
  }
  var input = el.previousElementSibling;
  var iframe = document.createElement('iframe');
  iframe.style.cssText = 'display:none';
  iframe.src = '/_hcms/mem/bot-challenger-token?action=' + encodeURIComponent('passwordless');
  document.body.appendChild(iframe);
  function onMessage(e) {
    if (e.source !== iframe.contentWindow) return;
    if (e.origin !== window.location.origin) return;
    if (!e.data || e.data.type !== 'bot-challenger-token') return;
    input.value = e.data.token;
    window.removeEventListener('message', onMessage);
    document.body.removeChild(iframe);
  }
  window.addEventListener('message', onMessage);
})();
</script>

  
  <div class="hs-membership-loader hs_submit hs-submit">
    <div class="actions">
      <input id="hs-passwordless-submit" type="submit" class="hs-button primary large" value="Email link"  />
    </div>
  </div>
</form>
<script>
  document.getElementById('hs-passwordless-submit').disabled = true;
  document.querySelector("input[name=explicit_consent]").addEventListener('change',function(){
    if (this.checked){
      document.getElementById('hs-passwordless-submit').disabled=false;
    } else{
      document.getElementById('hs-passwordless-submit').disabled=true;
    }
  });
</script>

<script type="text/javascript">
  function onFormSubmit() {
//    document.querySelector('.hs-membership-loader').classList.add('active');
  }

  document.onkeydown = function(e) {
    if (['ArrowUp','ArrowDown'].includes(e.code)) {
      var children = [].slice.call(document.querySelectorAll('#hs-membership-form input:not([type="hidden"]):not([type="checkbox"]):not([disabled])'));
      for (i = 0; i < children.length; i++) {
        var input = children[i];
        if (input === document.activeElement) {
          if (e.code =='ArrowDown' && children[i+1] !== undefined) {
            children[i+1].focus();
            break;
          } else if (e.code=='ArrowUp' && children[i-1]!==undefined) {
            children[i-1].focus();
            break;
          }
        } else if (i + 1 === children.length) {
          children[0].focus();
        }
      }
    } else if ('Enter' === e.code) {
      e.preventDefault();
      var children = [].slice.call(document.querySelectorAll('#hs-membership-form input:not([type="hidden"]):not([type="checkbox"]):not([disabled])'));
      for (i = 0; i < children.length; i++) {
        var input=children[i];
        if (input ===  document.activeElement && children[i+1] !== undefined) {
          children[i+1].focus();
          break;
        } else if (input ===  document.activeElement && i + 1 === children.length) {
//          document.querySelector('.hs-membership-loader').classList.add('active');
          document.getElementById('hs-membership-form').submit();
        } else if (i + 1 === children.length) {
          children[0].focus();
        }
      }
    }
  }
</script>


<div id="hs-membership-rate-limit-error-text" style="display:none">
  You've made too many attempts at this request. Please try this action again in a few minutes.
</div>
<script type="text/javascript">
  function show_password(id) {
    var input = document.getElementById(id);
    input.type = input.type === 'password' ? 'text' : 'password';
  }
</script>
<script>
  function getCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
      var c = ca[i];
      while (c.charAt(0)==' ') c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
  }

  function setTracker() {
    var utkInput = document.getElementById('hs-membership-form-hubspotutk');
    if (!utkInput.value) {
      utkInput.value = getCookie("hubspotutk");
    }
  }

  setInterval(setTracker, 300);
</script>
</span> and friends are HubL tags, not modules — their markup is
   fixed and cannot be restructured. These ids and classes are the only handles
   they expose. Restyle freely; restructure not at all. */

.glow-auth__form .hs-form-field { margin-bottom: var(--glow-s3); }

.glow-auth__form label {
  display: block;
  font-family: var(--glow-font-body);
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--glow-muted);
  margin-bottom: 0.5rem;
}

.glow-auth__form input[type="email"],
.glow-auth__form input[type="password"],
.glow-auth__form input[type="text"] {
  width: 100%;
  box-sizing: border-box;
  font-family: var(--glow-font-body);
  font-size: var(--glow-body);
  color: var(--glow-ink);
  background: var(--glow-white);
  border: 1px solid var(--glow-border);
  border-radius: var(--glow-radius);
  padding: 0.85rem 1rem;
  transition: border-color var(--glow-dur) var(--glow-ease);
}

.glow-auth__form input[type="email"]:focus,
.glow-auth__form input[type="password"]:focus,
.glow-auth__form input[type="text"]:focus {
  outline: none;
  border-color: var(--glow-burgundy);
}

/* Remember-me is a checkbox and must not inherit the block label rule above. */
.glow-auth__form input[type="checkbox"] { margin-right: 0.5rem; }

/* HubSpot emits the checkbox BEFORE its label, for both remember-me and the
   passwordless consent. The adjacent-sibling rule catches every one of them,
   including any HubSpot adds later.

   Casing matters more than it looks here: the consent label is a legal
   statement ("I agree to allow Glow Cosmetique to store and process my personal
   data"), and the uppercase field-label treatment rendered it as two lines of
   11px small caps — the least readable form of the one sentence on this screen
   that has to be readable. */
.glow-auth__form input[type="checkbox"] + label {
  display: inline;
  font-size: var(--glow-small);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--glow-ink-soft);
}

/* "Show password" is emitted between the label and the input, so it read as a
   heading for the field rather than a control on it. Reorder visually; the DOM
   is fixed and cannot be touched. Scoped to password fields so the checkbox
   rows, which are not column-flex, are unaffected. */
.glow-auth__form .hs-form-field:has(input[type="password"]) {
  display: flex;
  flex-direction: column;
}

.glow-auth__form .hs-form-field:has(input[type="password"]) > label { order: 1; }
.glow-auth__form .hs-form-field:has(input[type="password"]) > input { order: 2; }

.glow-auth__form .hs-form-field:has(input[type="password"]) .hs-login-widget-show-password {
  order: 3;
  align-self: flex-end;
  margin-top: 0.4rem;
}

.glow-auth__form .hs-button,
.glow-auth__form input[type="submit"] {
  width: 100%;
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
  font-weight: 500;
  color: var(--glow-cream);
  background: var(--glow-burgundy);
  border: 1px solid var(--glow-burgundy);
  border-radius: 999px;
  padding: 0.9rem 1.75rem;
  cursor: pointer;
  transition: background var(--glow-dur) var(--glow-ease),
              border-color var(--glow-dur) var(--glow-ease);
}

.glow-auth__form .hs-button:hover,
.glow-auth__form input[type="submit"]:hover {
  background: var(--glow-deep);
  border-color: var(--glow-deep);
}

.glow-auth__form .actions { margin-top: var(--glow-s3); }

.glow-auth__form #hs_login_reset,
.glow-auth__form .hs-login-widget-show-password,
.glow-auth__form #hs-login-self-registration-link a {
  display: inline-block;
  margin-top: var(--glow-s2);
  font-size: var(--glow-small);
  color: var(--glow-burgundy);
  border-bottom: 1px solid transparent;
}

.glow-auth__form #hs_login_reset:hover,
.glow-auth__form .hs-login-widget-show-password:hover,
.glow-auth__form #hs-login-self-registration-link a:hover {
  border-color: var(--glow-burgundy);
}

/* Passwordless: whether it appears is a HubSpot setting, not a CSS decision.
   The agency theme hid it with display:none while leaving the endpoint live —
   that is not disabling it. Styled here so that if it IS on, it looks right. */
.glow-auth__form .form-separator {
  display: block;
  margin: var(--glow-s3) 0;
  font-size: var(--glow-small);
  color: var(--glow-muted);
  text-align: center;
}

/* Errors: amber, never red. A failed sign-in is not a failure state. */
.glow-auth__form .hs-error-msgs,
.glow-auth__form .hs-error-msg,
.glow-auth__form .form-input-validation-message {
  list-style: none;
  margin: 0.5rem 0 0;
  padding: 0;
  font-size: var(--glow-small);
  color: #8A5A2B;
}


/* ==========================================================================
   PORTAL SHELL
   ========================================================================== */

/* The frame does not scroll; only the content column does. Rail and top bar
   stay put without position:fixed. */
.glow-portal {
  display: flex;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  background: var(--glow-cream);
}

/* ---- Rail ---------------------------------------------------------------- */

.glow-rail {
  flex: none;
  width: 15rem;              /* 240px */
  background: var(--glow-white);
  border-right: 1px solid var(--glow-border);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: width var(--glow-dur) var(--glow-ease);
}

.glow-portal[data-rail="collapsed"] .glow-rail { width: 4rem; }  /* 64px */

/* The seam. This well is the same 56px as the top bar and carries the same
   bottom border, so the two form one continuous line across the viewport.
   Change one, change both. */
.glow-rail__well {
  flex: none;
  height: 56px;
  display: flex;
  align-items: center;
  padding-inline: var(--glow-s2);
  border-bottom: 1px solid var(--glow-border);
}

.glow-rail__mark {
  font-family: var(--glow-font-display);
  font-size: 1.125rem;
  letter-spacing: 0.02em;
  color: var(--glow-ink);
  white-space: nowrap;
  overflow: hidden;
}

/* Collapsed, the well is 64px and "Glow Cosmetique" truncated to "Glov" —
   a cut-off wordmark is the single most amateur thing a collapsed rail can do.
   Swap the full wordmark for a monogram instead of clipping it. */
.glow-rail__mark-short { display: none; }

.glow-portal[data-rail="collapsed"] .glow-rail__well { justify-content: center; padding-inline: 0; }
.glow-portal[data-rail="collapsed"] .glow-rail__mark-full { display: none; }
.glow-portal[data-rail="collapsed"] .glow-rail__mark-short { display: block; font-size: 1.375rem; }

.glow-rail__nav {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--glow-s3) 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
}

.glow-rail__link {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.65rem 0.75rem;
  border-radius: var(--glow-radius);
  font-size: var(--glow-small);
  font-weight: 500;              /* constant across all three states */
  color: var(--glow-muted);
  white-space: nowrap;
  transition: background var(--glow-dur) var(--glow-ease),
              color var(--glow-dur) var(--glow-ease);
}

.glow-rail__link:hover {
  background: var(--glow-cream);
  color: var(--glow-ink);
}

/* Active: tint fill + accent text. No bar, no bold, no icon change. */
.glow-rail__link[aria-current="page"] {
  background: var(--glow-blush);
  color: var(--glow-burgundy);
}

.glow-rail__icon { flex: none; width: 1.125rem; height: 1.125rem; }

.glow-portal[data-rail="collapsed"] .glow-rail__link { justify-content: center; padding-inline: 0.5rem; }
.glow-portal[data-rail="collapsed"] .glow-rail__label { display: none; }

/* ---- Rail footer --------------------------------------------------------- */

.glow-rail__foot {
  flex: none;
  padding: 0.75rem 0.5rem;
  border-top: 1px solid var(--glow-border);
}

/* The clinic, in the rail.

   Glow's portal has four pages where the Sigma portal has fourteen, so the rail
   has ~500px of dead column below the nav. Padding the nav with links to pages
   that do not exist would be faking it. This is the honest filler: static
   contact detail the client pulls when they want it.

   It is not a nudge. Nothing here contacts the client, scores them or prompts
   them — it answers "how do I ask about this?", which is the question a clinical
   record actually provokes. Sits at the bottom of the nav flow, above the
   attribution, and disappears entirely when the rail is collapsed. */
.glow-rail__help {
  margin-top: auto;
  padding: var(--glow-s3) 0.75rem var(--glow-s2);
}

.glow-rail__help-label {
  font-family: var(--glow-font-body);
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--glow-muted);
  margin: 0 0 0.5rem;
}

.glow-rail__help-phone {
  display: block;
  font-size: var(--glow-small);
  font-weight: 500;
  color: var(--glow-ink);
  border-bottom: 1px solid transparent;
  margin-bottom: 0.35rem;
}

.glow-rail__help-phone:hover { border-color: var(--glow-border); }

.glow-rail__help-hours {
  font-size: var(--glow-meta);
  line-height: 1.5;
  color: var(--glow-muted);
  margin: 0;
  max-width: none;
}

.glow-portal[data-rail="collapsed"] .glow-rail__help { display: none; }

/* Attribution at a whisper — present and findable, never competing. */
.glow-rail__credit {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  padding: var(--glow-s3) 0;
  margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--glow-border);
  text-align: center;
}

.glow-rail__credit-label {
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(122, 106, 98, 0.4);
}

.glow-rail__credit a {
  font-size: 0.6875rem;
  letter-spacing: 0.04em;
  color: var(--glow-muted);
  opacity: 0.55;
  transition: opacity var(--glow-dur) var(--glow-ease);
}

.glow-rail__credit a:hover { opacity: 1; }

/* The whole block, not its children. Hiding only the label and link left the
   padding and the bottom border behind — an empty bordered strip above the
   collapse button, which reads as a rendering fault. */
.glow-portal[data-rail="collapsed"] .glow-rail__credit { display: none; }

.glow-rail__toggle {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.65rem 0.75rem;
  border: 0;
  border-radius: var(--glow-radius);
  background: none;
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
  font-weight: 500;
  color: var(--glow-muted);
  cursor: pointer;
  text-align: left;
}

.glow-rail__toggle:hover { background: var(--glow-cream); color: var(--glow-ink); }
.glow-portal[data-rail="collapsed"] .glow-rail__toggle { justify-content: center; padding-inline: 0.5rem; }

/* ---- Top bar ------------------------------------------------------------- */

.glow-portal__main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.glow-topbar {
  flex: none;
  height: 56px;                       /* matches .glow-rail__well exactly */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--glow-s3);
  padding-inline: var(--glow-s3);
  background: var(--glow-white);
  border-bottom: 1px solid var(--glow-border);
}

.glow-topbar__title {
  font-size: var(--glow-small);
  font-weight: 500;
  color: var(--glow-ink);
  white-space: nowrap;
}

.glow-topbar__right {
  display: flex;
  align-items: center;
  gap: var(--glow-s3);
}

.glow-topbar__who {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  white-space: nowrap;
}

.glow-topbar__phone {
  font-size: var(--glow-small);
  font-weight: 500;
  color: var(--glow-ink);
  white-space: nowrap;
}

.glow-topbar__signout {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  border-bottom: 1px solid transparent;
  white-space: nowrap;
}

.glow-topbar__signout:hover { color: var(--glow-ink); border-color: var(--glow-border); }

.glow-burger--portal {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.glow-burger--portal span {
  display: block;
  height: 1px;
  width: 100%;
  background: var(--glow-ink);
}

/* ---- Content column ------------------------------------------------------ */

/* THE GROUND IS DEEPER THAN THE CARDS, and that is the whole of what "contained
   in bubbles" means. Page --glow-cream (#FAF7F2) against white cards is a ~2%
   luminance step: technically two surfaces, visually one, so nothing ever reads
   as an object sitting ON something. MPS runs roughly #F5F5F4 under white and
   its cards lift immediately.

   Deepening the ground rather than adding shadow keeps the rule at the top of
   this file intact — elevation is a 1px border, no shadows on content, ever. */
.glow-portal__content {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  background: #F2EEE7;
  padding: clamp(1.25rem, 3vw, 2rem);
}

/* The cap is PER PAGE, not baked into the shell. Sigma's shell is
   <main className="flex-1 overflow-y-auto"> with no cap at all; individual
   pages apply max-w-3xl (768px) or max-w-2xl (672px) where the content is
   document-like, and leave the dashboard and list pages full width to fill with
   card grids. Capping in the shell forces every future page into a reading
   column, which will be wrong for the results list the moment it exists.

   Set `portal_width` in the page template: "reading" (default) | "wide". */
.glow-portal__inner { max-width: none; }
.glow-portal__inner--reading { max-width: 48rem; }   /* 768px — Sigma's max-w-3xl */
/* 992px. For the result record: wide enough that a tabular row breathes, narrow
   enough that a range bar's two ends stay in one glance. Full width stretched a
   bar to ~700px and the marker stopped reading against its own limits. */
.glow-portal__inner--doc { max-width: 62rem; }

/* Every portal page needs one h1 for structure, but the top bar already states
   where you are — printing the same words again 140px below it is redundancy,
   not hierarchy. Pages whose heading would duplicate the top bar use this. */
.glow-portal__h1-sr {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.glow-portal__title {
  font-family: var(--glow-font-display);
  font-size: var(--glow-pt-h1);
  line-height: 1.15;
  letter-spacing: -0.015em;
  color: var(--glow-ink);
  margin: 0 0 var(--glow-s4);
}

/* A heading and the lead that belongs to it are ONE unit. Without this the h1's
   own 2rem bottom margin pushes the lead away from it, and the lead reads as an
   orphaned paragraph rather than as the subtitle. */
.glow-portal__title:has(+ .glow-lead) { margin-bottom: var(--glow-s2); }

/* The lead keeps .glow-lead's own 48ch measure — capped on WIDE pages too,
   because prose wants a measure even where the page below it fills the field
   with cards. This adds only the gap down to the first section. */
.glow-portal__title + .glow-lead { margin-bottom: var(--glow-s5); }

/* Space above EVERY section, not just between siblings. The adjacent-sibling
   form left the first section jammed against whatever preceded it — on the
   archetype page that is the panel, and the eyebrow landed 11px under it.
   Zeroed for a section that opens the page, where the h1 already sets the gap. */
.glow-portal__section { margin-top: var(--glow-s5); }
.glow-portal__section:first-child { margin-top: 0; }

/* ── THE EYEBROW. One definition, everywhere. ────────────────────────────────
   Normalized 5 Aug 2026. There were SIX uppercase-label treatments across this
   file — .glow-block__t, .glow-portal__eyebrow, .glow-sec__grp-t,
   .glow-labnote__t, .glow-relby__k, .glow-dochdr .k, .glow-whois__facts b —
   at 10px/11px/12px, weights 500 and 600, and tracking from 0.06em to 0.18em.

   Nobody chose six. Each was written next to the component it labels, each was
   reasonable in isolation, and the differences are only visible when you put
   two sections beside each other — which is exactly what the overview does.

   The composed rule is `.glow-eyebrow`; the historic class names are kept as
   aliases so no template has to change to get the fix. COLOUR stays with the
   component (muted by default, burgundy on a lab note), because colour carries
   meaning here and size does not.

   Section headers render whether or not the section has content. That single
   rule is why zero-state pages read as structured rather than broken. */
.glow-eyebrow,
.glow-portal__eyebrow,
.glow-sec__grp-t,
.glow-labnote__t,
.glow-relby__k,
.glow-dochdr .k,
.glow-block__t,
.glow-whois__facts b {
  font-family: var(--glow-font-body);
  font-size: var(--glow-pt-label);
  font-weight: 600;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--glow-muted);
}

.glow-portal__eyebrow { margin: 0 0 var(--glow-s3); }


/* Two columns on the wide pages, one on reading pages and mobile. Sigma fills
   its dashboard this way — cards, not a longer column.

   The container is __inner, NOT the grid itself. A container query cannot style
   its own container, so `container-type` and the queried rule on the same
   element silently does nothing — which is exactly what happened here the first
   time, and to the archetype panel before it. If a grid ever fails to split,
   this is the first thing to check. */
.glow-portal__inner { container-type: inline-size; }

.glow-portal__grid {
  display: grid;
  gap: var(--glow-s3);
}

@container (min-width: 40rem) {
  .glow-portal__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* A tile is a card you can enter. The whole thing is the target, so the arrow
   is an affordance rather than the hit area. */
.glow-tile {
  display: flex;
  flex-direction: column;
  gap: var(--glow-s2);
  background: var(--glow-white);
  border: 1px solid var(--glow-border);
  border-radius: var(--glow-radius);
  padding: var(--glow-s4);
  transition: border-color var(--glow-dur) var(--glow-ease);
}

a.glow-tile:hover { border-color: var(--glow-muted); }

.glow-tile__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--glow-s2);
}

/* ── THE SERIF TITLE. One size for every card, tile and section. ─────────────
   Normalized 5 Aug 2026. There were four, all within 4px: .glow-card__title
   1.125rem, .glow-tile__title 1.25rem, .glow-sec__t 1.375rem,
   .glow-portal__title 1.75rem.

   Four sizes inside 4px is not a hierarchy — a reader cannot perceive a 2px
   step as rank, so it registers as inconsistency instead. Two levels is the
   whole scale a portal needs: the page is 28px, everything inside it is 20px.
   The thing that separates a card from a section is the eyebrow above it and
   the box around it, both of which are already doing that work. */
.glow-tile__title,
.glow-card__title,
.glow-sec__t {
  font-family: var(--glow-font-display);
  font-size: var(--glow-pt-card);
  line-height: 1.2;
  color: var(--glow-ink);
  margin: 0;
}

.glow-tile__body {
  font-size: var(--glow-small);
  line-height: 1.6;
  color: var(--glow-muted);
  margin: 0;
  max-width: none;
}

/* An optional fact under the body — a date, a position. Set in ink rather than
   muted so it reads as the tile's one piece of real content, and separated by a
   hairline so it does not run on from the description as another sentence.

   A fact, never a figure. Nothing computed, nothing compared. */
.glow-tile__meta {
  margin: 0;
  padding-top: var(--glow-s2);
  border-top: 1px solid var(--glow-border);
  font-size: var(--glow-meta);
  letter-spacing: 0.01em;
  color: var(--glow-ink-soft);
}

/* Pushes the link to the bottom so tiles of different text lengths still line
   their actions up. */
.glow-tile__foot { margin-top: auto; padding-top: var(--glow-s2); }


/* ==========================================================================
   CARDS AND STATES
   ========================================================================== */

.glow-card {
  background: var(--glow-white);
  border: 1px solid var(--glow-border);
  border-radius: var(--glow-radius);
}

/* A SECOND surface weight, and the portal needs one. Every card being white on
   cream with the same hairline gives a page no hierarchy — it reads as a stack
   of equal claims, which is what made these pages feel soft. Explanatory asides
   ("what this is", "why the order matters") sit on the tinted ground so the
   client's OWN record stays the white, foreground surface.

   Tint only. No shadow, no gradient — composition does the work here. */
.glow-card--soft {
  background: var(--glow-blush);
  border-color: transparent;
}

.glow-card--soft .glow-card__body p { color: var(--glow-ink-soft); }
.glow-card--soft .glow-note { border-left-color: rgba(109, 41, 50, 0.25); }

/* --glow-light is the divider on a WHITE card; on the blush ground it is very
   nearly the ground itself and the rows read as one block. One step darker. */
.glow-card--soft .glow-card__rows > * + * { border-top-color: var(--glow-border); }

/* position:relative anchors the "?" explainer panel; the flex row is what keeps
   the "?" on the title's baseline instead of dropping to its own line. */
.glow-card__head {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--glow-s2);
  padding: var(--glow-head-y) var(--glow-s4);
  border-bottom: 1px solid var(--glow-border);
}

/* Serif, because a card title is a heading and Instrument Serif IS the brand —
   a portal set entirely in 14px Inter throws away the identity every public
   page spends its budget establishing.
   Size now comes from --glow-pt-card, shared with .glow-tile__title and
   .glow-sec__t — see the note above .glow-tile__title. */

.glow-card--soft .glow-card__head { border-bottom-color: var(--glow-border); }

.glow-card__body { padding: var(--glow-s4); }

/* Cards in a grid stretch to the tallest sibling, so a short card's action would
   float mid-air. Pushes the last note or link to the bottom edge. */
.glow-card { display: flex; flex-direction: column; }
.glow-card__body { flex: 1; }

/* Reading prose inside a card is a step LARGER than the surrounding UI — 17px
   against the portal's 14px. That was previously an accident of inheritance;
   it is kept on purpose, because a paragraph a client actually reads and a
   label they scan are different jobs. Anything structural inside a card
   (rows, meta, status) stays at --glow-small. */
.glow-card__body p {
  font-size: var(--glow-body);
  line-height: 1.7;
  color: var(--glow-ink-soft);
}

.glow-card__body p + p { margin-top: var(--glow-s3); }

/* Rules WITHIN a card are one step lighter than the card's own edge, so nested
   lists never compete with the outline. */
.glow-card__rows > * + * { border-top: 1px solid var(--glow-light); }

.glow-card__row {
  display: flex;
  align-items: center;
  gap: var(--glow-s3);
  padding: var(--glow-s3) var(--glow-s4);
  transition: background var(--glow-dur) var(--glow-ease);
}

a.glow-card__row:hover { background: var(--glow-cream); }

.glow-card__row-title { font-size: var(--glow-small); font-weight: 500; color: var(--glow-ink); }

/* Definition rows — label column fixed so the values share a left edge. Without
   it the values start wherever their label happened to end, which reads as
   ragged rather than tabular. Opt-in, because the results list wants its title
   to take the space instead. Collapses on narrow containers. */
.glow-card__rows--spec .glow-card__row-title { flex: 0 0 10rem; }

@container (max-width: 30rem) {
  .glow-card__rows--spec .glow-card__row { flex-direction: column; gap: 0.25rem; align-items: start; }
  .glow-card__rows--spec .glow-card__row-title { flex: none; }
}
/* Meta sits at the RIGHT edge of the row. Fixed 5 Aug 2026, reported by Hemi
   against the review page.

   Only `__row-arrow` carried `margin-left: auto`, so a row with an arrow pushed
   its trailing element right and a row WITHOUT one did not — the meta simply sat
   against the title with 400px of empty row beside it. Measured: title at 305,
   meta at 454, row 990 wide.

   Every page that pairs a title with a status chip is the no-arrow case, so this
   was every status row in the portal, not an edge case.

   Spec rows opt out: they are label/value definition pairs whose values share a
   left edge on purpose, and pushing the value to the far side of the card
   un-tabulates exactly what --spec exists to line up. */
/* ── THE ROUTINE-LEVEL INSTRUCTION.
   Added 5 Aug 2026 — Hemi: "what's going on here?" against a card whose intro
   paragraph sat flush to the card edge at lead size while the rows below it
   were indented 32px.

   Cause: `.glow-block .glow-card__body { padding: 0 }` (line ~1754). That is
   correct for a card inside a block — the block supplies the padding — but it
   means a card that ALSO has its own body loses it, and the paragraph fell to
   the card's outer edge while the rows kept their own.

   The real answer is that this content was never a card body. It is a rule that
   governs every row beneath it — "no makeup the following day, no actives for
   seven days" — so it is an INTRO ROW: same 32px inset as the rows, divided
   from them, and set at row-title weight rather than as a lead paragraph. A
   lead-sized sentence above a 14px list inverts the hierarchy of the card, since
   the instruction is context and the steps are the subject. */
.glow-card__intro {
  padding: var(--glow-s3) var(--glow-s4);
  margin: 0;
  font-size: var(--glow-small);
  line-height: 1.55;
  color: var(--glow-ink-soft, var(--glow-ink));
  border-bottom: 1px solid var(--glow-light);
  background: var(--glow-cream);
}

.glow-card__row-meta { font-size: var(--glow-small); color: var(--glow-muted); margin-left: auto; }
.glow-card__rows--spec .glow-card__row-meta { margin-left: 0; }
.glow-card__row-title { flex: 1 1 auto; min-width: 0; }
.glow-card__rows--spec .glow-card__row-title { flex: 0 0 10rem; }
.glow-card__row-arrow { margin-left: auto; color: var(--glow-burgundy); }

/* A note under the row title. The instruction is the load-bearing half of a
   skin plan — "only at night, 1–2 times a week to start" is the difference
   between using an acid correctly and stripping a barrier with it — so it is a
   block under the product, not a parenthetical beside it. */
.glow-card__row-note {
  display: block;
  margin-top: 0.25rem;
  font-weight: 400;
  font-size: var(--glow-meta);
  line-height: 1.5;
  color: var(--glow-muted);
}

/* ---- Empty states --------------------------------------------------------
   Draw the card. Icon at low opacity as furniture, never as subject. Then say
   what is true, and — the part that matters — WHO will put something here and
   WHEN. Never "no data". */

.glow-empty {
  background: var(--glow-white);
  border: 1px solid var(--glow-border);
  border-radius: var(--glow-radius);
  padding: var(--glow-s5) var(--glow-s4);
  text-align: center;
}

/* display:block is load-bearing, not tidiness. An <svg> is inline by default,
   and `margin: 0 auto` does nothing to an inline box — the mark sits on the
   text baseline instead of centring above the title. */
.glow-empty__icon {
  display: block;
  width: 1.5rem;
  height: 1.5rem;
  margin: 0 auto var(--glow-s2);
  color: var(--glow-muted);
  opacity: 0.35;
}

.glow-empty__title {
  font-size: var(--glow-small);
  font-weight: 500;
  color: var(--glow-ink);
  margin: 0 0 0.35rem;
  max-width: none;
}

.glow-empty__body {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  margin: 0 auto;
  max-width: 42ch;
}

/* ---- Status ------------------------------------------------------------
   Words, not numbers, wherever a human is in the loop. Worst case is amber;
   nothing here is ever red. */

.glow-status {
  display: inline-block;
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: var(--glow-radius-sm);
  padding: 0.3rem 0.7rem;
  border: 1px solid transparent;
}

.glow-status--ready   { background: var(--glow-blush); color: var(--glow-burgundy); border-color: #E6D2CE; }
.glow-status--waiting { background: #F6EFE4; color: #8A5A2B; border-color: #EADDC6; }
.glow-status--quiet   { background: var(--glow-light); color: var(--glow-muted); border-color: var(--glow-border); }

/* A location, never a score. "Module 6 of 12" — count in ink, any qualifier
   muted. No bars, no percentages, no zero states rendered as 0%. */
.glow-position { font-size: var(--glow-small); color: var(--glow-muted); }
.glow-position strong { font-weight: 500; color: var(--glow-ink); }

.glow-note {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  border-left: 2px solid var(--glow-border);
  padding-left: var(--glow-s3);
  margin: var(--glow-s3) 0 0;
}

/* ── THE LINK ROW. ───────────────────────────────────────────────────────────
   Added 5 Aug 2026. A standalone `.glow-link` under a card or a block appeared
   NINE times across six templates, every one of them as
   `<p style="margin-top: var(--glow-s3)">` — and three of the nine had drifted
   to s2 and s5, so the same affordance sat at three different distances
   depending on which page you were on.

   Nobody chose that either. There was no class, so each author wrote the gap
   inline, and an inline style is invisible to the next author. A missing
   component does not stay missing; it gets re-invented once per file. */
.glow-linkrow {
  margin: var(--glow-s3) 0 0;
}

/* A quiet dated fact under a position — "Started June 2026". Was three type
   declarations written inline in portal-course.html, which is how a template
   ends up owning the design. */
.glow-startedon {
  margin: var(--glow-s2) 0 0;
  font-size: var(--glow-small);
  color: var(--glow-muted);
}


/* ==========================================================================
   ARCHETYPE PANEL — the one dramatic surface in the portal
   ========================================================================== */

/* Two columns: a mark rail, then everything else. Single column stacks it.
   The split is a CONTAINER query, not a media query, because this panel renders
   at ~960px in the portal and at whatever the QA grid gives it — a viewport
   query splits a 500px card as if it were full width and the result is cramped.

   Composition is borrowed from the Skin Revision Skin Code section, which is
   the same content on the same dark field: mark left, text right, one measure.
   Numbers from src/components/SkinCodeSection.tsx — a 2-col grid with a wide
   gap, body line-height ~1.9, and a coloured rather than grey eyebrow. */
.glow-archetype {
  container-type: inline-size;
  /* Ambient wash in the archetype's own colour, top-right, well clear of the
     text column. Flat --glow-deep read as dead space at this size; this gives
     the six cards distinct temperature for free, and gives the chip colour a
     reason to exist beyond the chip. Kept at 16% so cream text stays legible. */
  background:
    radial-gradient(ellipse at 78% 12%,
      color-mix(in srgb, var(--glow-arch-color, var(--glow-burgundy)) 16%, transparent) 0%,
      transparent 62%),
    var(--glow-deep);
  border-radius: var(--glow-radius);
  padding: clamp(1.75rem, 4vw, 2.75rem);
  color: rgba(250, 247, 242, 0.72);
}

/* The grid lives on __inner, not on .glow-archetype, because a container query
   cannot style its own container — only its descendants. Putting both the
   container-type and the queried rule on the same element silently does
   nothing, which is exactly how it failed the first time. */
.glow-archetype__inner {
  display: grid;
  align-items: start;
  gap: var(--glow-s4);
}

/* The text column is capped, not the individual paragraphs. Capping each
   element separately (40ch tagline, 52ch definition, 56ch dual) gave three
   different right edges stacked on each other and left the column under-filled.
   One cap, in one place, and every block shares an edge.

   The column is 1fr, not a fixed max, so the hairlines run to the card's full
   inset rather than stopping short of it. The MEASURE is therefore set by the
   card's own max-width — 50rem gives a ~62ch column, which is the target. Any
   layout using this panel should cap the card near 50rem for the same reason. */
@container (min-width: 34rem) {
  .glow-archetype__inner {
    grid-template-columns: 7rem minmax(0, 1fr);
    gap: var(--glow-s5);
  }
}

/* The archetype's own colour arrives as an inline custom property so the value
   stays in the data and the rule stays here. Fallback keeps a missing hex from
   rendering transparent. */
.glow-archetype__chip {
  width: 7rem;
  height: 7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--glow-radius);
  background: var(--glow-arch-color, var(--glow-burgundy));
  box-shadow: inset 0 0 0 1px rgba(36, 28, 26, 0.12);   /* keeps the pale chips visible */
}

/* Height-constrained only. Two of the six symbols are 100x120 and four are
   100x100 — constrain height, let width follow, and neither distorts. */
.glow-archetype__symbol {
  height: 3.5rem;
  width: auto;
  color: var(--glow-cream);
}

/* Rose, not grey. The Skin Revision section uses rgba(200,140,150,0.85) for the
   same eyebrow; a neutral grey here made the whole card read monochrome brown. */
.glow-archetype__code {
  font-family: var(--glow-font-body);
  font-size: var(--glow-tag);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(214, 158, 166, 0.85);
  margin: 0 0 var(--glow-s2);
  max-width: none;
}

.glow-archetype__name {
  font-family: var(--glow-font-display);
  /* cqi, not vw. This sits in a 768px card but was clamped against the
     VIEWPORT, so at 1440 it resolved to 48px — larger than anything in the
     Sigma portal, whose biggest type is 30-32px — while the card it lives in
     never changed width. Same class of mistake as querying the wrong box.
     The panel already establishes a container, so size off that. */
  font-size: clamp(1.75rem, 5cqi, 2.25rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--glow-cream);
  margin: 0 0 var(--glow-s2);
}

.glow-archetype__tagline {
  font-family: var(--glow-font-display);
  font-style: italic;
  font-size: 1.25rem;
  line-height: 1.4;
  color: rgba(250, 247, 242, 0.8);
  margin: 0 0 var(--glow-s3);
  max-width: none;   /* the column is the measure — see __inner */
}

/* One measure for the prose, and the generous leading the reference uses —
   1.9 there, 1.85 here because this sits a step smaller. */
.glow-archetype__definition {
  font-size: var(--glow-small);
  line-height: 1.85;
  color: rgba(250, 247, 242, 0.72);
  max-width: none;   /* the column is the measure — see __inner */
  margin: 0;
}

/* Secondary archetype. Rendered only when a secondary exists AND differs from
   the primary — live data contains at least one record where they are equal.

   ORDER MATTERS: this block sits AFTER the definition, never before it. It was
   between the tagline and the definition, which meant the card explained the
   SECONDARY archetype before it had explained the primary one, and dropped two
   hairlines through the optical centre. Define the thing, then qualify it. */
.glow-archetype__dual {
  margin-top: var(--glow-s4);
  padding-top: var(--glow-s3);
  border-top: 1px solid rgba(250, 247, 242, 0.14);
}

.glow-archetype__dual-label {
  font-size: var(--glow-small);
  color: rgba(250, 247, 242, 0.6);
  margin: 0 0 0.35rem;
  max-width: none;
}

.glow-archetype__dual-label strong { font-weight: 500; color: rgba(250, 247, 242, 0.9); }

.glow-archetype__dual-body {
  /* --glow-meta, not an ad-hoc 13px. The portal had 11/13/14 all doing
     similar work within a 3px band, which the eye reads as inconsistency
     rather than hierarchy. 12px is far enough from 14 to be legible as a
     step. */
  font-size: var(--glow-meta);
  line-height: 1.65;
  color: rgba(250, 247, 242, 0.5);
  margin: 0;
  max-width: none;   /* the column is the measure — see __inner */
}

/* The rule above the actions is unconditional. Previously the dual block was
   the only thing drawing rules, so a card with a secondary and a card without
   read as two different components. Now the grammar is constant: everything
   below the definition is separated by a hairline, secondary or not. */
.glow-archetype__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--glow-s3) var(--glow-s4);
  margin-top: var(--glow-s4);
  padding-top: var(--glow-s3);
  border-top: 1px solid rgba(250, 247, 242, 0.14);
}

.glow-archetype__actions .glow-link { color: rgba(250, 247, 242, 0.75); }
.glow-archetype__actions .glow-link:hover { border-color: rgba(250, 247, 242, 0.5); }

/* Quiet, but legible — 0.55 alpha on the deep field, not the 0.4 the timestamp
   uses. A qualifier nobody can read is decoration. */
.glow-archetype__caveat {
  font-size: var(--glow-small);
  line-height: 1.6;
  color: rgba(250, 247, 242, 0.55);
  border-top: 1px solid rgba(250, 247, 242, 0.14);
  padding-top: var(--glow-s3);
  margin: var(--glow-s4) 0 0;
  max-width: 52ch;
}

.glow-archetype__meta {
  font-size: 0.8125rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(250, 247, 242, 0.4);
  margin: var(--glow-s4) 0 0;
  max-width: none;
}

/* The caveat already draws the rule; a second gap under it doubles the space. */
.glow-archetype__caveat + .glow-archetype__meta { margin-top: var(--glow-s2); }


/* ==========================================================================
   QA harness — templates/portal-archetype-qa.html only
   ========================================================================== */

/* Single column, capped at the portal's content width, so each card renders at
   the size it will actually be. The two-column grid was the harness lying: it
   showed the panel at ~500px, which is a width it never has in the portal, and
   the unequal card heights left voids that read as a design fault when they
   were a harness fault. One column, real width, honest review. */
.glow-qa { display: grid; gap: var(--glow-s5); max-width: 50rem; }

.glow-qa__label {
  font-family: var(--glow-font-body);
  font-size: var(--glow-tag);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--glow-muted);
  margin: 0 0 0.5rem;
}

/* ---- DUTCH display harness — portal-results-qa.html ---------------------
   These primitives are on trial, not adopted. If an option wins, its rules
   move up into the CARDS section and the rest are deleted rather than left
   lying around for someone to reach for by accident. */

.glow-qa__inner { padding: var(--glow-s5) var(--glow-gutter); max-width: 58rem; margin: 0 auto; }
.glow-qa__h1 { font-family: var(--glow-font-display); font-size: 2.25rem; line-height: 1.1; margin: 0 0 var(--glow-s2); }
.glow-qa__block { margin-top: var(--glow-s6); }
.glow-qa__note { font-size: var(--glow-small); line-height: 1.7; color: var(--glow-ink-soft); max-width: 62ch; margin: 0 0 var(--glow-s3); }
.glow-qa__row { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--glow-s3); }
.glow-qa__card { text-align: center; }
.glow-qa__val { font-family: var(--glow-font-display); font-size: 1.75rem; margin: var(--glow-s1) 0 0; }
.glow-qa__val span { font-family: var(--glow-font-body); font-size: var(--glow-meta); color: var(--glow-muted); margin-left: 0.3rem; }
.glow-qa__metric { font-size: var(--glow-small); color: var(--glow-muted); margin: 0.15rem 0 0; }

.glow-tag-pill {
  display: inline-block;
  font-size: var(--glow-tag);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  background: var(--glow-blush);
  color: var(--glow-burgundy);
  border-radius: var(--glow-radius-sm);
  padding: 0.35rem 0.85rem;
  margin: 0 0 var(--glow-s3);
}

.glow-dial { width: 100%; max-width: 150px; height: auto; }

/* ---- THE ANALYTE ROW — adopted 3 Aug 2026 ------------------------------
   One reference range, drawn and LABELLED, with the client's result on it.

   Three things the first pass got wrong, all of which made it read as a mock:

   1. THE BAND WAS INVISIBLE. --glow-blush on --glow-light is a ~4% luminance
      step; at 6px tall the reference range — the single most important mark on
      the row — could not be seen. It now carries its own tint and a hairline.
   2. THE LIMITS WERE NOT PRINTED. The lab's own dial prints 1.8 and 4.5. A band
      with no numbers tells a client where she sits without telling her what she
      sits inside, which is most of the information gone.
   3. EVERY ROW READ AT ONE WEIGHT. Out-of-range now moves the marker and the
      status word to burgundy, and draws the distance from the band edge to the
      marker. The DISTANCE is the information — not a red/green grade.

   Still no traffic lights: burgundy marks "outside the expected range", which is
   a fact, not "bad", which would be a verdict the clinic has not given. */

/* THE ROW, RETUNED 3 Aug. Hemi: "it somehow feels muddy and the rows tend to
   blend into each other and you think 'what does this even say and what do I do
   with it?'"

   Diagnosis, and it was not subtle once counted: FIVE type sizes per row —
   15px name, 13px plain, 12px status, 17px value, 11px unit — with three of
   them in near-identical greys (#241C1A, #4A3E39, #7A6A62), all left-aligned and
   stacked with 2px between them. Three lines of similar grey text at similar
   sizes is one grey blob, not a hierarchy.

   Worse: THE STATUS WORD WAS THE FAINTEST THING ON THE ROW. It is the answer to
   "what do I do with it", and it was third in the stack in the lightest colour
   on the page.

   Three changes:
     1. Two lines left (name, plain), never three. The status moves right, beside
        the value, where the eye lands after crossing the bar.
     2. The greys separate. Name goes to full ink at 500; plain drops to a
        genuinely lighter tone so it reads as subordinate rather than competing.
     3. A fixed row rhythm, so a two-line plain does not make one row 20px taller
        than its neighbours and turn the column ragged. */

.glow-metric {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(6rem, 1fr) minmax(8rem, auto);
  align-items: center;
  gap: var(--glow-s3);
  min-height: 4.75rem;
  padding: 0.9rem var(--glow-s4);
}
/* One step darker than --glow-light. At 50-odd rows the lighter rule stopped
   separating anything and the table read as a single field of text. */
.glow-metric + .glow-metric { border-top: 1px solid var(--glow-border); }

.glow-metric__id { min-width: 0; }
.glow-metric__name {
  display: block; font-size: var(--glow-pt-row); font-weight: 500;
  line-height: 1.3; color: var(--glow-ink);
}
.glow-metric__plain {
  display: block; font-size: 0.8125rem; line-height: 1.4;
  color: rgba(36, 28, 26, 0.5); margin-top: 0.2rem;
}

.glow-metric__v { text-align: right; white-space: nowrap; }
.glow-metric__v b {
  font-weight: 500; font-size: 1.125rem; letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums; color: var(--glow-ink);
}
.glow-metric__v > span { font-size: var(--glow-tag); color: var(--glow-muted); margin-left: 0.3rem; }
.glow-metric__status {
  display: block; font-style: normal; font-size: 0.75rem;
  line-height: 1.3; color: var(--glow-muted); margin-top: 0.3rem;
  white-space: normal;
}
.glow-metric--out .glow-metric__status { color: var(--glow-flag); font-weight: 500; }

.glow-bar { position: relative; height: 34px; }
.glow-bar__rail { position: absolute; left: 0; right: 0; top: 15px; height: 1px; background: var(--glow-border); }
.glow-bar__band {
  position: absolute; top: 9px; height: 13px; border-radius: 7px;
  background: rgba(109, 41, 50, 0.13);
  border: 1px solid rgba(109, 41, 50, 0.30);
}
.glow-bar__cap { position: absolute; top: 6px; width: 1px; height: 19px; background: rgba(109, 41, 50, 0.55); }
/* Drawn ONLY when the value falls outside the band. */
.glow-bar__gap { position: absolute; top: 15px; height: 1px; background: var(--glow-flag); }
.glow-bar__mark {
  position: absolute; top: 8.5px; width: 15px; height: 15px; margin-left: -7.5px;
  border-radius: 50%; background: var(--glow-ink);
  box-shadow: 0 0 0 3px var(--glow-white), 0 1px 4px rgba(36, 28, 26, 0.30);
}
.glow-metric--out .glow-bar__mark { background: var(--glow-flag); }
/* A hairline down the left edge of a flagged row. At a glance down 25 rows this
   is what finds the five that matter — the marker alone is too small a target. */
.glow-metric--out { box-shadow: inset 3px 0 0 var(--glow-flag); background: rgba(168,100,30,0.028); }
.glow-bar__lim {
  position: absolute; top: 25px; transform: translateX(-50%);
  font-size: var(--glow-tag); font-variant-numeric: tabular-nums;
  color: rgba(36, 28, 26, 0.45); white-space: nowrap;
}

/* No verified cycle context → no band. The marker still shows the value; what is
   withheld is the comparison, which is the part that would be wrong. */
.glow-bar--nocontext .glow-bar__rail {
  background: repeating-linear-gradient(90deg, var(--glow-border) 0 4px, transparent 4px 8px);
}

.glow-key { display: flex; flex-wrap: wrap; gap: var(--glow-s3); font-size: var(--glow-meta); color: var(--glow-muted); margin: 0 0 var(--glow-s2); }
.glow-key span { display: inline-flex; align-items: center; gap: 0.5rem; }
.glow-key i { width: 26px; height: 11px; border-radius: 6px; background: rgba(109,41,50,.10); border: 1px solid rgba(109,41,50,.22); }
.glow-key u { width: 11px; height: 11px; border-radius: 50%; background: var(--glow-ink); box-shadow: 0 0 0 2px var(--glow-white); }

/* ---- The "?" explainer -------------------------------------------------
   Glow cannot diagnose. It CAN say what a marker is and why it bears on skin,
   which is the difference between a client understanding her result and
   googling it at 11pm. <details> so it works with no JS at all. */
.glow-hx { margin-left: auto; position: relative; }
.glow-hx summary {
  list-style: none; cursor: pointer;
  width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--glow-border);
  display: grid; place-items: center;
  font-size: var(--glow-meta); font-weight: 500; color: var(--glow-muted);
  transition: all var(--glow-dur) var(--glow-ease);
}
.glow-hx summary::-webkit-details-marker { display: none; }
.glow-hx summary:hover { border-color: var(--glow-ink); color: var(--glow-ink); }
.glow-hx[open] summary { background: var(--glow-ink); border-color: var(--glow-ink); color: var(--glow-cream); }
.glow-hx__p {
  position: absolute; right: 0; top: 32px; width: min(29rem, 80vw);
  background: var(--glow-white); border: 1px solid var(--glow-border);
  border-radius: 14px; padding: 1.25rem 1.4rem;
  box-shadow: 0 12px 40px rgba(36, 28, 26, 0.13);
  z-index: 10; font-size: var(--glow-small); line-height: 1.68; color: var(--glow-ink-soft);
}
.glow-hx__p p { margin: 0 0 0.75rem; } .glow-hx__p p:last-child { margin: 0; }
.glow-hx__p b { color: var(--glow-ink); font-weight: 500; }

@container (max-width: 46rem) {
  .glow-metric { grid-template-columns: 1fr auto; gap: 0.5rem var(--glow-s2); }
  .glow-bar { grid-column: 1 / -1; }
}

.glow-curve { width: 100%; height: auto; display: block; }
.glow-curve__axis {
  display: flex; justify-content: space-between;
  font-size: var(--glow-meta); color: var(--glow-muted); margin-top: 0.4rem;
}

@media (max-width: 600px) {
  .glow-qa__row { grid-template-columns: 1fr; }
  .glow-qa__metric-row { flex-wrap: wrap; }
  .glow-qa__metric-name { flex: 1 1 100%; }
  .glow-qa__metric-val { flex: 0 0 auto; }
}


/* ==========================================================================
   RESPONSIVE
   Below 940px the rail leaves the flow and becomes a drawer holding the same
   markup, so there is one nav to maintain rather than two.
   ========================================================================== */

@media (max-width: 939px) {
  .glow-portal { height: auto; min-height: 100vh; overflow: visible; display: block; }

  .glow-rail {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 120;
    width: 17rem;
    transform: translateX(-100%);
    transition: transform var(--glow-dur) var(--glow-ease);
  }

  .glow-portal[data-drawer="open"] .glow-rail { transform: none; }

  .glow-portal__scrim {
    position: fixed;
    inset: 0;
    z-index: 110;
    background: rgba(36, 28, 26, 0.45);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--glow-dur) var(--glow-ease);
  }

  .glow-portal[data-drawer="open"] .glow-portal__scrim { opacity: 1; pointer-events: auto; }

  .glow-portal__content { overflow: visible; }

  /* No collapse control in a drawer — it has nothing to collapse into. And with
     the button gone, the credit's divider would be separating it from nothing,
     so that goes too. A rule with no content under it reads as a broken layout. */
  .glow-rail__toggle { display: none; }
  .glow-rail__credit { border-bottom: 0; margin-bottom: 0; }
}

@media (min-width: 940px) {
  .glow-burger--portal,
  .glow-portal__scrim { display: none; }
}


/* ==========================================================================
   RESULT DETAIL — the DUTCH render, inside the portal shell
   ==========================================================================

   Adopted 3 Aug 2026. Hemi: *"I want the aesthetic, balance and styling"* of
   the MPS portal, explicitly NOT its gamification — so this borrows MPS's
   generosity of explanation and its entry points, and none of its 0% rings,
   progress bars or step counters. A clinical record that scores you is a record
   you perform for.

   The page is deliberately the most complex thing in the portal, and it is being
   built early rather than last: Hemi's reasoning is that the bar set here is the
   bar for everything after it. */

/* ---- The interpretation — the product ----------------------------------
   PORTAL.md: the interpretation is the product, the numbers are the raw
   material. So it opens the page, on the warm ground, with the nurse's name
   against it. A results page that leads with numbers is a lab printout. */
.glow-interp {
  background: var(--glow-blush);
  border-radius: 18px;
  padding: clamp(1.5rem, 4vw, 2rem) clamp(1.5rem, 4vw, 2.25rem);
}
.glow-interp__who { display: flex; align-items: center; gap: 0.85rem; margin-bottom: var(--glow-s3); }
.glow-interp__av {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  background: var(--glow-burgundy); color: var(--glow-cream);
  display: grid; place-items: center;
  font-family: var(--glow-font-display); font-size: 1.05rem;
}
.glow-interp__n { display: block; font-size: var(--glow-pt-row); color: var(--glow-ink); }
.glow-interp__r { display: block; font-size: var(--glow-meta); color: var(--glow-muted); }
.glow-interp__body p {
  font-size: 1.125rem; line-height: 1.72; color: var(--glow-ink);
  margin: 0 0 var(--glow-s2); max-width: 56ch;
}
.glow-interp__body p:last-child { margin: 0; }
/* Pending is a designed state, not a gap. An unwritten interpretation is the
   normal condition for days after a result lands. */
.glow-interp__pending {
  border: 1px dashed rgba(109, 41, 50, 0.35);
  border-radius: 12px;
  padding: var(--glow-s3);
  background: rgba(255, 255, 255, 0.5);
}
.glow-interp__pending p { font-size: var(--glow-small); line-height: 1.65; color: var(--glow-ink-soft); margin: 0; max-width: 54ch; }
.glow-interp__pending strong { display: block; color: var(--glow-ink); font-weight: 500; margin-bottom: 0.35rem; }

/* ---- Orientation — three lines before any number ------------------------ */
.glow-orient { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: var(--glow-s3) var(--glow-s4); }
.glow-orient > div { border-top: 1px solid var(--glow-border); padding-top: 0.9rem; }
.glow-orient strong { display: block; font-weight: 500; color: var(--glow-ink); margin-bottom: 0.3rem; font-size: var(--glow-pt-row); }
.glow-orient p { margin: 0; font-size: var(--glow-small); line-height: 1.6; color: var(--glow-ink-soft); max-width: none; }

/* A section states what it covers BEFORE the numbers start. */
.glow-slead { font-size: 1rem; line-height: 1.7; color: var(--glow-ink-soft); max-width: 56ch; margin: 0 0 var(--glow-s3); }

/* ---- What happens now ---------------------------------------------------
   A result page that ends at the last number leaves the client holding
   something with nowhere to take it. */
.glow-next { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--glow-s2); }
.glow-next a {
  display: block; background: var(--glow-white);
  border: 1px solid var(--glow-border); border-radius: 14px;
  padding: 1.35rem 1.5rem;
  transition: border-color var(--glow-dur) var(--glow-ease);
}
.glow-next a:hover { border-color: var(--glow-muted); }
.glow-next strong { display: block; font-family: var(--glow-font-display); font-weight: 400; font-size: var(--glow-pt-card); color: var(--glow-ink); margin-bottom: 0.3rem; }
.glow-next span { display: block; font-size: var(--glow-small); line-height: 1.55; color: var(--glow-muted); }
.glow-next em { display: block; font-style: normal; font-size: var(--glow-small); color: var(--glow-burgundy); margin-top: 0.7rem; }

/* ---- The diurnal chart --------------------------------------------------
   Each of the four timed points has its OWN expected range, drawn as the block
   behind it. Plotting four differently-ranged values on one bare axis makes a
   mid-range bedtime reading look like a collapse next to a mid-range morning
   one — the blocks are what stop that. */
.glow-chart { width: 100%; height: auto; display: block; overflow: visible; }
.glow-chart .cg { stroke: var(--glow-light); stroke-width: 1; }
.glow-chart .cay { font: 400 10px var(--glow-font-body); fill: var(--glow-muted); }
.glow-chart .cbd { fill: rgba(109, 41, 50, 0.09); stroke: rgba(109, 41, 50, 0.20); }
.glow-chart .cbr { font: 400 10px var(--glow-font-body); fill: var(--glow-muted); }
.glow-chart .cdh { fill: var(--glow-white); }
.glow-chart .cdt { fill: var(--glow-burgundy); }
.glow-chart .cvv { font: 500 13px var(--glow-font-body); fill: var(--glow-ink); }
.glow-chart .cxx { font: 500 12px var(--glow-font-body); fill: var(--glow-ink-soft); }

/* ---- Document header strip ---------------------------------------------- */
.glow-dochdr {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--glow-s3) var(--glow-s4);
  border-top: 1px solid var(--glow-ink);
  padding-top: 1.1rem;
}
.glow-dochdr .k { display: block; margin-bottom: 0.3rem; }
.glow-dochdr .v { display: block; font-size: var(--glow-pt-row); color: var(--glow-ink); }

/* ---- The assumed-range caution ------------------------------------------ */
.glow-caution {
  background: #FBF6EC; border: 1px solid #EADDC6; border-left: 3px solid #C08A3E;
  border-radius: 14px; padding: var(--glow-s3) var(--glow-s4);
}
.glow-caution h2 { font-family: var(--glow-font-display); font-weight: 400; font-size: 1.25rem; color: #7A4E1D; margin: 0 0 0.5rem; }
.glow-caution p { color: #5E4426; margin: 0 0 0.75rem; font-size: var(--glow-pt-row); line-height: 1.7; max-width: 62ch; }
.glow-caution p:last-child { margin: 0; }


/* ---- Collapsible sections ------------------------------------------------
   Sixty analytes is not a page anyone reads top to bottom. Sections that hold
   nothing outside the expected range open COLLAPSED, with the summary on the
   header — "12 markers, all within range" is a complete answer for most people
   most of the time, and the detail is one click away for the rest.

   This is navigation, not scoring. It surfaces where to look using a fact the
   laboratory has already stated on its own report; it does not rank the client,
   grade her, or derive anything the lab did not print. */
.glow-sec { border: 1px solid var(--glow-border); border-radius: 16px; background: var(--glow-white); overflow: hidden; }
.glow-sec + .glow-sec { margin-top: var(--glow-s2); }
.glow-sec > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: baseline; gap: var(--glow-s2);
  padding: var(--glow-head-y) var(--glow-s4);
  transition: background var(--glow-dur) var(--glow-ease);
}
.glow-sec > summary::-webkit-details-marker { display: none; }
.glow-sec > summary:hover { background: var(--glow-cream); }
.glow-sec[open] > summary { border-bottom: 1px solid var(--glow-border); }
.glow-sec__t { line-height: 1.15; }
.glow-sec__c { font-size: var(--glow-small); color: var(--glow-muted); }
.glow-sec__c b { font-weight: 500; color: var(--glow-flag); }
/* The chevron rotates; it is the only motion on the page. */
.glow-sec__chev { margin-left: auto; width: 16px; height: 16px; color: var(--glow-muted); transition: transform var(--glow-dur) var(--glow-ease); flex: none; align-self: center; }
.glow-sec[open] .glow-sec__chev { transform: rotate(180deg); }
.glow-sec__lead { font-size: var(--glow-small); line-height: 1.7; color: var(--glow-ink-soft); max-width: 62ch; margin: 0; padding: var(--glow-s3) var(--glow-s4) 0; }
.glow-sec__grp { padding-top: var(--glow-s3); }
/* TIER 2 — names a group inside a section. Stays one step lighter than the
   block label so the nesting is legible without reading the words. */
.glow-sec__grp-t { margin: 0; padding: 0 var(--glow-s4) 0.75rem; }
.glow-sec__grp + .glow-sec__grp { border-top: 1px solid var(--glow-light); }

/* ---- The percentile slider ----------------------------------------------
   A DIFFERENT INSTRUMENT to the analyte bar, because it answers a different
   question. The bar asks "where does this value sit in its range"; the slider
   asks "how does this RATIO compare with everyone else's". Drawing them the
   same way would imply the two are comparable, and they are not — one is a
   measurement, the other is a population position.

   The lab prints these as "higher than 82% of the population". That phrasing is
   kept because rewording a percentile is how it becomes a grade. */
.glow-slider { padding: 1.15rem var(--glow-s4); }
.glow-slider + .glow-slider { border-top: 1px solid var(--glow-light); }
.glow-slider__h { display: flex; align-items: baseline; justify-content: space-between; gap: var(--glow-s2); margin-bottom: 0.15rem; }
.glow-slider__n { font-size: var(--glow-pt-row); color: var(--glow-ink); }
.glow-slider__v { font-size: var(--glow-pt-row); font-weight: 500; font-variant-numeric: tabular-nums; color: var(--glow-ink); }
.glow-slider__p { font-size: var(--glow-meta); color: var(--glow-ink-soft); margin: 0 0 0.8rem; line-height: 1.5; max-width: 60ch; }
.glow-slider__track {
  position: relative; height: 12px; border-radius: 6px;
  background: var(--glow-light); margin-bottom: 2.5rem;
}
/* The optimal band the lab shades on its own slider. */
.glow-slider__band { position: absolute; inset: 0 auto; height: 12px; border-radius: 6px; background: rgba(109,41,50,0.12); }
.glow-slider__mark {
  position: absolute; top: -3px; width: 2px; height: 18px;
  background: var(--glow-ink); border-radius: 1px; transform: translateX(-1px);
}
.glow-slider--out .glow-slider__mark { background: var(--glow-flag); }
.glow-slider__cap {
  position: absolute; top: 20px; transform: translateX(-50%);
  font-size: var(--glow-tag); font-variant-numeric: tabular-nums; color: var(--glow-muted); white-space: nowrap;
}
/* The ends sit BELOW the percentage caption, not on its line. The negative
   margin here pulled them up onto the same row, so a marker near either end put
   "82%" straight through "2-OH-E1" — invisible on a wide screen where the two
   are 500px apart, and unreadable at 390 where they are not. */
.glow-slider__ends {
  display: flex; justify-content: space-between; gap: var(--glow-s2);
  font-size: var(--glow-tag); color: var(--glow-muted); margin-top: -0.45rem;
}

/* ---- What you told us ---------------------------------------------------
   The self-reported comments from the requisition. They belong near the top
   because every range on the page is read against them — "reports regular
   cycles" is what justifies the luteal column. */
.glow-said { display: grid; gap: 0.65rem; }
.glow-said li {
  list-style: none; position: relative; padding-left: 1.4rem;
  font-size: 1rem; line-height: 1.6; color: var(--glow-ink-soft);
}
.glow-said li::before {
  content: ""; position: absolute; left: 0; top: 0.6em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--glow-burgundy); opacity: 0.45;
}

/* Two columns where the content is genuinely paired — cortisol beside
   cortisone, which is the comparison the lab itself invites. Balance rather
   than full-bleed everything, which was the note on the first pass. */
@container (min-width: 52rem) {
  .glow-pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--glow-s2); }
}


/* A section already draws the frame. Anything nested inside it must not draw a
   second one — the diurnal chart and the lab-note block both arrive as
   .glow-card and were rendering as cards-inside-a-card, which reads as a
   rendering fault rather than as structure. */
.glow-sec .glow-card { border: 0; border-radius: 0; background: transparent; }
.glow-sec .glow-card__head { padding-inline: var(--glow-s4); }


/* The lab's commentary block, now at the TOP of its section — you read the
   finding, then the evidence. Same order the page already uses for the RN's
   note, and it saves scrolling 25 rows to be told what they meant.

   Tinted, so the lab's voice is visibly not Glow's voice. Three voices on this
   page and the reader should never have to work out which one is speaking. */
.glow-labnote {
  background: var(--glow-blush);
  border-bottom: 1px solid var(--glow-border);
  padding: var(--glow-s3) var(--glow-s4);
}
/* Attribution, not hierarchy — burgundy is doing the work of saying "this is
   someone else speaking", so it does not also need size. */
.glow-labnote__t { color: var(--glow-burgundy); margin: 0 0 0.85rem; }
.glow-labnote .glow-said li { font-size: var(--glow-pt-row); color: var(--glow-ink-soft); }
.glow-labnote .glow-note { margin-top: var(--glow-s3); border-left-color: rgba(109,41,50,0.25); }


/* ---- The steroid pathway ------------------------------------------------
   Rebuilt 3 Aug. Hemi on v1: "this looks old Windows 95 basic."

   Three things were doing that, and none of them was the idea:
     · orthogonal elbow connectors with arrowheads — the visual signature of a
       process diagram, not a biological pathway. Now cubic beziers.
     · every node an identical dashed pill, so nothing had rank
     · one colour for everything, so three distinct branches read as one tangle

   Each branch now carries its own hue, and this is where per-system colour
   EARNS its place: it is doing structural work here (which chain am I on)
   rather than decorating rows. Amber is untouched and still means only "outside
   the expected range" — none of these three is amber. */

.glow-path { width: 100%; height: auto; display: block; overflow: visible; }

.glow-path .pth path { fill: none; stroke-width: 1.5; stroke-linecap: round; }
.glow-path .br-p, .glow-path .pth .br-p { stroke: #B08A6B; }
.glow-path .br-a, .glow-path .pth .br-a { stroke: #A8556A; }
.glow-path .br-c, .glow-path .pth .br-c { stroke: #6E7F63; }
.glow-path .pth .br-x { stroke: var(--glow-border); }

.glow-path .nd rect { fill: #fff; stroke-width: 1.25; }
.glow-path .nd text {
  font: 500 13.5px var(--glow-font-body); fill: var(--glow-ink);
  text-anchor: middle; dominant-baseline: middle;
}
.glow-path .nd .br-p rect { stroke: #B08A6B; fill: #FBF4EE; }
.glow-path .nd .br-a rect { stroke: #A8556A; fill: #FBF0F1; }
.glow-path .nd .br-c rect { stroke: #6E7F63; fill: #F2F5F0; }

/* Not-measured: a ring and a label, no box, no dashes. It sits on the chain
   without competing with the markers that have a value behind them. */
.glow-path .nd--off circle { fill: #fff; stroke: var(--glow-border); stroke-width: 1.5; }
.glow-path .nd--off text {
  font: 400 12.5px var(--glow-font-body); fill: var(--glow-muted);
  text-anchor: start; dominant-baseline: middle;
}

.glow-path .nd__key text { font: 400 11.5px var(--glow-font-body); fill: var(--glow-muted); dominant-baseline: middle; }
.glow-path .nd__key .k-off { fill: #fff; stroke: var(--glow-border); stroke-width: 1.5; }
.glow-path .nd__key .k-on { fill: #FBF0F1; stroke: #A8556A; stroke-width: 1.25; }

/* FOLLOW ONE BRANCH — no JavaScript. Hovering anywhere on the diagram fades
   every branch; hovering a branch restores it. Focus-within does the same from
   the keyboard, and :hover simply never fires on touch, where the whole diagram
   stays legible at full strength. Nothing is hidden and nothing is required. */
.glow-path .br-p, .glow-path .br-a, .glow-path .br-c {
  transition: opacity var(--glow-dur) var(--glow-ease);
}
.glow-path:hover .br-p, .glow-path:hover .br-a, .glow-path:hover .br-c { opacity: 0.22; }
.glow-path .br-p:hover, .glow-path .br-a:hover, .glow-path .br-c:hover,
.glow-path:hover .pth .br-p:hover, .glow-path:hover .pth .br-a:hover { opacity: 1; }
/* A branch's connectors light with its nodes — they share the class, so hovering
   the group in either layer restores both. */
.glow-path:hover .pth path { opacity: 0.22; }
.glow-path .nd .br-p:hover ~ *, .glow-path .nd .br-a:hover ~ * { opacity: inherit; }

@media (prefers-reduced-motion: reduce) {
  .glow-path .br-p, .glow-path .br-a, .glow-path .br-c { transition: none; }
}

.glow-path { width: 100%; height: auto; display: block; overflow: visible; }




/* ---- Reviewed and released ----------------------------------------------
   What replaced the RN's written interpretation. A STATEMENT OF FACT — a nurse
   read this, and when — not a reading of the panel. Deliberately small and
   deliberately not a card: it is a provenance line, and giving it a card would
   re-create the authority claim it exists to remove.

   Hemi, 3 Aug: what the results change "belongs on the skin journey process",
   so this points there and says nothing itself. */
.glow-relby { border-left: 2px solid var(--glow-burgundy); padding: 0.15rem 0 0.15rem var(--glow-s3); }
.glow-relby__k { display: block; }
.glow-relby__v { display: block; font-size: 1rem; color: var(--glow-ink); margin-top: 0.25rem; }
.glow-relby__p { font-size: var(--glow-pt-row); line-height: 1.65; color: var(--glow-ink-soft); max-width: 56ch; margin: var(--glow-s2) 0 0; }


/* ==========================================================================
   BLOCKS — one idea, one container
   ==========================================================================

   Hemi, 3 Aug, against the MPS portal: *"things are contained cleanly here in
   bubbles or modules… Glow looks much better but still a distance off."*

   Two structural differences, and neither is decoration:

   1. THE EYEBROW WAS OUTSIDE THE CARD. Glow floated section labels on the page
      and then drew a card under them, which is an editorial magazine pattern —
      a standfirst above a plate. MPS puts the label INSIDE, as a header row with
      a rule under it, so the label and its content are visibly one object. On a
      page of fifteen sections the difference is whether it reads as a stack of
      modules or as a continuous scroll with headings in it.

   2. NOTHING NESTS TWICE. A card inside a block draws no second frame — the
      block already drew it. The same rule .glow-sec needed.

   A .glow-block is one idea: a header that names it and a body that is it. */

.glow-block {
  background: var(--glow-white);
  border: 1px solid var(--glow-border);
  border-radius: 16px;
  margin-top: var(--glow-s3);
  overflow: hidden;
}
.glow-block:first-child { margin-top: 0; }
/* The first block after the page title — the title and lead sit on the ground
   as a page header, so this needs its own gap rather than butting the lead. */
.glow-block--first { margin-top: var(--glow-s4); }
/* Inside a block the strip has already been framed, so it drops the rule that
   made it a standalone header on the page. */
.glow-block .glow-dochdr { border-top: 0; padding-top: 0; }

.glow-block__head {
  display: flex; align-items: baseline; gap: var(--glow-s2);
  padding: var(--glow-head-y) var(--glow-s4);
  border-bottom: 1px solid var(--glow-border);
}
/* TIER 1 — names a whole block. It was 11px, 500, 0.16em tracking in --glow-muted,
   which is the weakest type on the page carrying the most structural weight.
   At 11px the letterforms are too small to hold that much tracking: the word
   dissolves into evenly-spaced marks.

   12px, 600, and less tracking. Bigger letters need less space between them,
   not more — the tracking was compensating for a size that was already wrong. */
.glow-block__t { color: var(--glow-ink-soft); margin: 0; }
.glow-block__note { font-size: var(--glow-meta); color: var(--glow-muted); margin-left: auto; }
.glow-block__body { padding: var(--glow-s4); }
.glow-block__body > :first-child { margin-top: 0; }
.glow-block__body > :last-child { margin-bottom: 0; }

/* Nested surfaces stand down — the block is the container. */
.glow-block .glow-card { border: 0; border-radius: 0; background: transparent; }
.glow-block .glow-card__body { padding: 0; }
.glow-block .glow-sec { border-radius: 12px; }
.glow-block .glow-sec .glow-card__body { padding: var(--glow-s4); }

/* A block whose body IS a list of sections needs no padding of its own. */
.glow-block--flush .glow-block__body { padding: var(--glow-s3); background: #FAF8F5; }


/* ---- The pathway on a phone ---------------------------------------------
   The diagram is 1000 units wide with 13.5px labels. Scaled into a 284px column
   those labels render at under 4px — present, and unreadable.

   So it keeps a legible minimum and its container scrolls. 860px holds the text
   at ~11.6px, which is the smallest it stays comfortably readable at. Above
   900px the cap lifts and it behaves exactly as before. */
.glow-path-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.glow-path-hint {
  display: none; font-size: var(--glow-meta); color: var(--glow-muted);
  margin: 0.6rem 0 0;
}
@media (max-width: 899px) {
  .glow-path { min-width: 860px; }
  .glow-path-hint { display: block; }
  /* The scroller needs the block's padding back, so the diagram can run to the
     edge of the screen instead of stopping short of it. */
  .glow-block__body > .glow-card .glow-path-scroll {
    margin-inline: calc(var(--glow-s4) * -1);
    padding-inline: var(--glow-s4);
  }
}


/* ==========================================================================
   MOBILE — four defects found on a real device, 3 Aug
   ========================================================================== */

@media (max-width: 620px) {

  /* 1. THE PATHWAY WAS MOSTLY EMPTY CANVAS.
     Holding an 860px minimum in a 412px window shows 48% of the diagram — and
     because the trunk sits at x=440 of 1000, the visible left-hand slice is the
     part with nothing in it. The client scrolls into a blank field and has to
     work out that the picture is somewhere off to the right.

     Fixing it by scrolling further was the wrong instinct. The fix is to make
     the WHOLE diagram fit the scroll, and buy back legibility by enlarging the
     type inside the SVG instead of the SVG itself. At 620px the 1000-unit
     viewBox renders at 0.62 — so 19 units lands at ~11.8px, which reads, and
     the entire chain is reachable in ~200px of scroll rather than 450. */
  .glow-path { min-width: 620px; }
  .glow-path .nd text { font-size: 19px; }
  .glow-path .nd--off text { font-size: 18px; }
  .glow-path .nd__key text { font-size: 16px; }

  /* 2. THE SECTION HEADER WRAPPED THROUGH ITSELF.
     Serif title, marker count and chevron on one flex row is fine at 992px and
     falls apart at 412 — the title breaks to two lines and the count breaks
     mid-phrase, which reads as a rendering fault rather than a long heading. */
  .glow-sec > summary { flex-wrap: wrap; align-items: center; padding-right: 3rem; position: relative; }
  
  .glow-sec__t { flex: 1 1 100%; }
  .glow-sec__c { flex: 1 1 100%; margin-top: 0.2rem; }
  .glow-sec__chev { position: absolute; right: var(--glow-s3); top: 1.35rem; margin: 0; }

  /* 2b. THE TILE STATUS CHIP WRAPPED INSIDE ITS OWN PILL.
     Measured 4 Aug at 390: "After your first visit" and "Runs on The Skin Code"
     both rendered 49px tall against the 30px of the short ones — a two-line
     badge, which reads as a break rather than a label.

     The chips got longer on purpose. They now name whose move it is instead of
     saying "Not started" at everything, and that is worth more than brevity, so
     the layout gives way rather than the words.

     Chip first, title under it — an eyebrow label, which is a deliberate
     pattern rather than a squeezed one. Same wrap trick as the section header
     above: order swaps them, and 100% basis on the title forces the break. */
  .glow-tile__head { flex-wrap: wrap; align-items: flex-start; gap: var(--glow-s1) var(--glow-s2); }
  .glow-tile__head .glow-status { order: 1; }
  .glow-tile__title { order: 2; flex: 1 1 100%; }

  /* 3. FIVE STACKED ROWS OF METADATA before the client reaches anything.
     Two up, and it is a quarter of the height. */
  .glow-dochdr { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--glow-s3) var(--glow-s2); }

  /* 4. THE LAB'S BULLETS GAVE UP 28px OF A 340px COLUMN to an indent, on the
     longest passages of text on the page. */
  .glow-said li { padding-left: 1rem; }
  .glow-said li::before { width: 5px; height: 5px; }

  /* The scroll hint belongs with the diagram, not adrift under the legend. */
  .glow-path-hint { margin-top: 0.35rem; font-style: italic; }

  /* 5. NESTED PADDING COMPOUNDS, and on a 412px screen it eats the page.
     block body 24 + section 0 + lab-note 32 + bullet indent 16 = 72px of left
     inset before a word appears, and the same again on the right — leaving the
     longest prose on the page in a ~200px column.

     Each container is individually reasonable; it is the STACK that is wrong,
     and it is only ever visible on a narrow screen. Every level steps down. */
  .glow-block__body,
  .glow-block--flush .glow-block__body { padding: var(--glow-s2); }
  .glow-block__head { padding-inline: var(--glow-s2); }
  .glow-labnote { padding: var(--glow-s3) var(--glow-s2); }
  .glow-sec > summary { padding-inline: var(--glow-s2); padding-right: 2.75rem; }
  .glow-sec__lead { padding-inline: var(--glow-s2); }
  .glow-sec__grp-t { padding-inline: var(--glow-s2); }
  .glow-metric { padding-inline: var(--glow-s2); }
  .glow-slider { padding-inline: var(--glow-s2); }
  .glow-sec .glow-card__body { padding: var(--glow-s2); }
  .glow-sec__chev { right: var(--glow-s2); }
  .glow-block__body > .glow-card .glow-path-scroll {
    margin-inline: calc(var(--glow-s2) * -1);
    padding-inline: var(--glow-s2);
  }

  /* 5b. THE STEP-DOWN MISSED THE FOUR COMPONENTS THE OVERVIEW IS MADE OF.
     Added 5 Aug. Everything above steps down; .glow-tile, .glow-card__body,
     .glow-card__row and .glow-empty did not — so on a 390px screen the results
     pages breathed and the overview, which is the page every client opens
     first, still carried a 32px inset on every side of every card.

     It was invisible in review because the pages that were being reviewed
     closely at the time were the DUTCH ones, and those were fixed. The overview
     was never opened at 390 after the tiles were built. */
  .glow-tile { padding: var(--glow-s2); }
  .glow-card__body { padding: var(--glow-s2); }
  .glow-card__head { padding-inline: var(--glow-s2); }
  .glow-card__row,
  .glow-card__intro { padding-inline: var(--glow-s2); }
  .glow-empty { padding: var(--glow-s4) var(--glow-s2); }
}

/* A document that does not exist yet is not a link. Same frame, no affordance,
   and it says who puts it there — the empty-state rule applied to a file. */
.glow-next__pending {
  display: block; background: var(--glow-white);
  border: 1px dashed var(--glow-border); border-radius: 14px;
  padding: 1.35rem 1.5rem;
}
.glow-next__pending strong { display: block; font-family: var(--glow-font-display); font-weight: 400; font-size: var(--glow-pt-card); color: var(--glow-ink); margin-bottom: 0.3rem; }
.glow-next__pending span { display: block; font-size: var(--glow-small); line-height: 1.55; color: var(--glow-muted); }
.glow-next__pending em { display: block; font-style: normal; font-size: var(--glow-small); color: var(--glow-muted); margin-top: 0.7rem; }


/* ---- The client strip ----------------------------------------------------
   Sits under the top bar on every portal page. A record header, not a
   dashboard: name, where they are seen, and two facts about the past.

   Deliberately absent: visit counts, rings, percentages, streaks, "next step".
   This is the single most-seen element in the portal and therefore the one
   where a scoring habit would do the most damage. */
.glow-whois {
  flex: none;
  display: flex; align-items: center; gap: var(--glow-s2);
  padding: 0.85rem clamp(1.25rem, 3vw, 2rem);
  background: var(--glow-white);
  border-bottom: 1px solid var(--glow-border);
}
.glow-whois__av {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  background: var(--glow-blush); color: var(--glow-burgundy);
  display: grid; place-items: center;
  font-family: var(--glow-font-display); font-size: 1rem;
}
.glow-whois__id { min-width: 0; }
.glow-whois__n { display: block; font-size: var(--glow-pt-row); font-weight: 500; color: var(--glow-ink); line-height: 1.25; }
.glow-whois__m { display: block; font-size: var(--glow-meta); color: var(--glow-muted); }
.glow-whois__facts { display: flex; gap: var(--glow-s4); margin-left: auto; }
.glow-whois__facts span { display: block; font-size: 0.8125rem; color: var(--glow-ink); white-space: nowrap; }
.glow-whois__facts b { display: block; margin-bottom: 0.1rem; }
/* On a phone the facts drop rather than crush the name. They are context, and
   the name is the thing that has to survive. */
@media (max-width: 620px) { .glow-whois__facts { display: none; } }

/* The closing aside on the overview sits further from the grid above it than a
   note normally does — it is a change of subject, not a footnote to the last
   card. Was an inline margin. */
.glow-note--spaced { margin-top: var(--glow-s4); }

/* The unit beside a slider value. Was a three-property inline style inside a
   macro, which is the least discoverable place a font-size can live. */
.glow-slider__u {
  font-weight: 400;
  color: var(--glow-muted);
  font-size: var(--glow-meta);
}

/* A link row that follows prose rather than a card — half the gap. */
.glow-linkrow--tight { margin-top: var(--glow-s2); }

/* The laboratory's own disclaimer, set as a pull quote. Serif and larger than
   the prose around it BECAUSE it is the protection: data/dutch/REFERENCE.md §2
   says never paraphrase, and typography that treats it as fine print invites
   exactly that. Was three inline declarations. */
.glow-labquote {
  font-family: var(--glow-font-display);
  font-size: var(--glow-pt-card);
  line-height: 1.45;
  color: var(--glow-ink);
}
.glow-labquote__src {
  font-size: var(--glow-small);
  color: var(--glow-muted);
}

/* ── FAQ, PORTAL WEIGHT ─────────────────────────────────────────────────────
   Added 5 Aug 2026 for /portal/help.

   The public `.glow-faq` (_page.css:476) is deliberately grand — 22px serif
   questions, 32px of vertical padding each — because on /faq the questions ARE
   the page and there is nothing else competing. In the portal that same rule
   turns twelve short answers into four screens of scrolling, and it re-opens
   the size problem the type pass just closed: 1.375rem is not on the portal
   scale.

   So this restyles the same ELEMENT rather than introducing a second one. The
   markup is a bare <details><summary>, which means the public component's
   __q/__a classes are absent and cannot collide. One class name, two weights,
   scoped by container — the alternative was `.glow-faq--portal` on every one
   of twelve entries, which is a modifier that exists only because two pages
   have different densities. */
.glow-block .glow-faq {
  border-bottom: 1px solid var(--glow-light);
}
.glow-block .glow-faq:last-child { border-bottom: 0; }

.glow-block .glow-faq > summary {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--glow-s3);
  cursor: pointer;
  list-style: none;
  font-size: var(--glow-pt-row);
  font-weight: 500;
  line-height: 1.45;
  color: var(--glow-ink);
  padding: var(--glow-s3) 0;
}
.glow-block .glow-faq > summary::-webkit-details-marker { display: none; }

.glow-block .glow-faq > summary::after {
  content: '+';
  flex: none;
  font-family: var(--glow-font-body);
  /* An icon drawn with a character, not a size on the scale — it is sized to
     sit on the summary's baseline and rotate to a cross. */
  font-size: 1.125rem; /* lint-exempt: glyph */
  line-height: 1;
  color: var(--glow-burgundy);
  transition: transform var(--glow-dur) var(--glow-ease);
}
.glow-block .glow-faq[open] > summary::after { transform: rotate(45deg); }

.glow-block .glow-faq > div {
  padding-bottom: var(--glow-s3);
  max-width: 62ch;
}
.glow-block .glow-faq > div p {
  font-size: var(--glow-small);
  line-height: 1.7;
  color: var(--glow-ink-soft);
  margin: 0 0 var(--glow-s2);
}
.glow-block .glow-faq > div p:last-child { margin-bottom: 0; }
.glow-block .glow-faq > div .glow-note { margin-top: var(--glow-s2); }

/* Numbered instructions — the app install, and nothing else so far. Numerals
   in burgundy because they are the one place in the portal where the ORDER is
   load-bearing: doing step three before step two on an iPhone lands you in the
   wrong menu. */
.glow-steps-list {
  margin: 0 0 var(--glow-s2);
  padding-left: 1.35rem;
  font-size: var(--glow-small);
  line-height: 1.7;
  color: var(--glow-ink-soft);
}
.glow-steps-list li { margin-bottom: 0.4rem; }
.glow-steps-list li::marker { color: var(--glow-burgundy); font-weight: 600; }
.glow-steps-list strong { color: var(--glow-ink); font-weight: 600; }

/* ── THE CREDIT MARK ────────────────────────────────────────────────────────
   Added 5 Aug 2026. Hemi asked for the MPS logo in the rail foot, matching the
   pattern SigmaSync's portal uses — label above, lockup below — "just make it
   the right size and a greyscale".

   THE SIZE IS SET BY THE THINNEST LINE, NOT BY THE MARK. Ink extents measured
   rather than guessed: the triangle is 51% of the lockup's height, MYPIXEL
   17%, and STRATEGY 14.6% — and STRATEGY is a thin outline face, which is the
   first thing to turn to mush. At 5.5rem wide the whole lockup is 62px tall,
   which puts STRATEGY at ~9px: legible, and small enough to stay a credit.

   Going larger would read as co-branding. Going smaller loses the second word,
   and a wordmark with one legible line is worse than no wordmark — the same
   finding as the Glow lockup in the rail well.

   GREYSCALE IS THE POINT, NOT A PREFERENCE. Three saturated triangles in a
   palette of cream, ink and one burgundy would be the most colourful thing on
   the page, sitting at the bottom of the rail, competing with the client's own
   record. 45% opacity matches the text link it replaced. */
.glow-rail__credit-mark {
  display: block;
  line-height: 0;
}

.glow-rail__credit-mark img {
  display: block;
  width: 5.5rem;
  height: auto;
  filter: grayscale(1);
  opacity: 0.45;
  transition: opacity var(--glow-dur) var(--glow-ease);
}

.glow-rail__credit-mark:hover img { opacity: 0.7; }

/* .glow-next and .glow-next__pending carry the invitation and the pending
   document — both are card TITLES in every sense that matters, so they take
   --glow-pt-card like every other one. They were 1.125rem, which was the last
   serif size sitting off the portal scale. */

/* ==========================================================================
   PRINT — the one document a client carries out of here
   ==========================================================================

   Added 5 August 2026.

   WHY THIS EXISTS. A client takes her hormone results to a GP. That is the
   whole reason the results pages are built the way they are — the laboratory's
   own words kept verbatim, the reference ranges shown rather than summarised,
   the nurse's interpretation attributed and dated. All of that is there so the
   page survives being read by a second clinician.

   And then it printed with a navigation rail down the side, a top bar, and
   every disclosure panel collapsed.

   APP 12 gives a client the right to a copy of what an organisation holds
   about her. `/portal/data` makes that requestable. This makes the most
   important one usable the moment she wants it, without asking anybody — which
   is the difference between a right and a process.

   THE DECISIONS ARE ALL THE SAME DECISION: what does a GP need on paper.
   · No rail, no top bar, no collapse chevrons — furniture for a screen.
   · Every <details> forced open. A folded section on paper is a missing
     section, and the folded ones are the in-range markers, which is exactly
     what a second opinion checks first.
   · Backgrounds off, hairlines kept. The reference BAND stays, because a value
     without its range is not a result.
   · Links print their href — a paper page cannot be clicked, and the lab's own
     documents are the most likely thing to be followed up.
   · No orphaned rows: a marker and its range never break across a page.       */

@media print {

  .glow-rail,
  .glow-topbar,
  .glow-whois,
  .glow-portal__scrim,
  .glow-rail__toggle,
  .glow-burger { display: none !important; }

  .glow-portal,
  .glow-portal__main,
  .glow-portal__content {
    display: block !important;
    background: #fff !important;
    padding: 0 !important;
    margin: 0 !important;
    overflow: visible !important;
    height: auto !important;
  }

  body { background: #fff; }

  /* Every disclosure open. A section folded on paper has simply vanished. */
  .glow-sec,
  .glow-faq,
  .glow-hx { display: block !important; }
  .glow-sec > summary::after,
  .glow-sec__chev,
  .glow-faq > summary::after,
  .glow-hx > summary { display: none !important; }
  .glow-sec > summary { padding-inline: 0 !important; }

  /* Card frames become rules. Ink on paper is expensive and a printed portal
     full of tinted panels is a photocopy of a website rather than a document. */
  .glow-block,
  .glow-card,
  .glow-sec,
  .glow-idcard,
  .glow-next a,
  .glow-labnote {
    background: #fff !important;
    border-color: #ccc !important;
    box-shadow: none !important;
    break-inside: auto;
  }

  /* A marker and its range are one object. Splitting them across a page break
     puts a number on one sheet and its meaning on another. */
  .glow-metric,
  .glow-slider,
  .glow-card__row,
  .glow-relby { break-inside: avoid; }

  .glow-block__head,
  .glow-card__head { break-after: avoid; }

  /* The reference band is the only fill that survives — a value without its
     range is not a result, it is a number. */
  .glow-bar__band { background: #e8e8e8 !important; print-color-adjust: exact; }
  .glow-bar__mark { background: #000 !important; print-color-adjust: exact; }
  .glow-metric--out .glow-bar__mark { background: #000 !important; }

  /* Paper has no hover, so a link has to carry its destination. Internal
     portal links are dropped — they are unreachable from paper anyway — and
     only real URLs and the clinic number are spelled out. */
  a[href^="http"]::after,
  a[href^="tel:"]::after {
    content: " (" attr(href) ")";
    font-size: 9pt;
    color: #555;
    word-break: break-all;
  }
  a[href^="tel:"]::after { content: " (" attr(href) ")"; }

  /* Who released it and when is the first thing a GP looks for, so it is not
     allowed to be quiet on paper. */
  .glow-relby { border-left-color: #000 !important; }

  /* Provenance in the footer of every sheet. A printed clinical page with no
     source is worth very little to whoever reads it next. */
  @page { margin: 18mm 16mm; }
}

/* ── Overview furniture ─────────────────────────────────────────────────────
   Added 5 Aug 2026 with the overview rebuild. */

/* The greeting sits ABOVE the h1 and is deliberately smaller than it. She is
   being greeted; the page is still called "your record". Inverting that —
   "Good evening, Sarah" as the h1 — makes the page about the salutation. */
.glow-greeting {
  font-size: var(--glow-small);
  color: var(--glow-muted);
  margin: 0 0 var(--glow-s1);
}

/* The base-details strip. Sits under the lead, above everything that can be
   empty, so the page has one thing on it that is true for every client from
   the first day. A frame rather than a bare grid, because it is a statement of
   record and the frame is what says so. */
.glow-idcard {
  background: var(--glow-white);
  border: 1px solid var(--glow-border);
  border-radius: var(--glow-radius);
  padding: var(--glow-s3) var(--glow-s4);
  margin-bottom: var(--glow-s4);
}
.glow-idcard .glow-dochdr { border-top: 0; padding-top: 0; }

/* WHAT WE DECIDED AGAINST.
   Set apart from the summary above it on purpose. A refusal is the most
   valuable and most easily skimmed-past line in the whole record, and running
   it on as a second paragraph is exactly how it gets read as a caveat rather
   than as a decision. Burgundy because this is the house position, not a
   warning — there is no red anywhere in this portal. */
.glow-declined {
  margin-top: var(--glow-s3);
  padding-top: var(--glow-s3);
  border-top: 1px solid var(--glow-light);
}
.glow-declined .glow-eyebrow {
  display: block;
  color: var(--glow-burgundy);
  margin: 0 0 var(--glow-s1);
}
.glow-declined p:last-child { margin-bottom: 0; }

@media (max-width: 620px) {
  .glow-idcard { padding: var(--glow-s2); }
}

/* ── THE TRACK — a process drawn as a path ──────────────────────────────────
   Added 5 Aug 2026. Hemi pointed at skinrevision.com.au/#bldm and asked for
   somewhere in the portal that feels "alive" as well as clean.

   What is there is a five-node progress track: a 9px burgundy dot per phase, a
   1px hairline at 25% opacity flexing between them, a very small label beneath
   each. Arrival · Brief · Drop · Journey · Close. It reads as a path rather
   than a paragraph, which is the whole reason it holds attention.

   ─────────────────────────────────────────────────────────────────────────
   ⚠ THE ONE RULE THAT MAKES THIS LEGAL HERE, AND IT IS EASY TO BREAK.

   NO NODE IS EVER MARKED AS "YOURS". Every dot is the same weight, the same
   colour, always.

   The Skin Revision track describes what ONE session contains — it is
   descriptive, and nothing on it is current. The moment a node lights up to
   show where the client has got to, the same component becomes a progress
   indicator with dots instead of a bar, and `CLAUDE.md` bans those outright.

   The distinction is not decorative: a described process invites understanding,
   a tracked one invites a feeling about how far along you are. This portal is a
   case file. It may explain what happens; it may not score her against it.

   `ui.position()` remains the ONLY way a location is ever stated — "Module 6 of
   8", in words, once. Never on this. */
.glow-track {
  display: flex;
  align-items: flex-start;
  margin: var(--glow-s3) 0 0;
}

.glow-track__node {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  flex: none;
}

.glow-track__dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--glow-burgundy);
  flex: none;
}

.glow-track__label {
  font-size: var(--glow-pt-label);
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--glow-burgundy);
  white-space: nowrap;
}

/* The connector. Sits on the dots' centre line, so it is nudged up by half the
   label's height rather than centred on the node as a whole. */
.glow-track__link {
  flex: 1 1 0%;
  height: 1px;
  background: rgba(109, 41, 50, 0.25);
  margin: 4px 6px 0;
}

/* Below ~30rem five nodes cannot hold their labels side by side without the
   words colliding, so the track turns vertical: dots down the left, labels
   beside them, connector becomes the rule between. Same information, and it
   still reads as a sequence rather than a list. */
@container (max-width: 30rem) {
  .glow-track { flex-direction: column; align-items: stretch; }
  .glow-track__node { flex-direction: row; gap: 0.75rem; justify-content: flex-start; }
  .glow-track__link { flex: none; width: 1px; height: 14px; margin: 2px 0 2px 4px; }
}


/* ==========================================================================
   Platform override layer — MUST be the last thing in main.css
   ==========================================================================

   HubSpot generates a stylesheet from the theme settings (fields.json) and
   injects it INLINE in <head> via standard_header_includes — which lands after
   our linked main.css. At equal specificity the later rule wins, so the
   boilerplate's defaults were beating the entire Glow design system.

   What it was doing, measured on the live page:
     html   font-size: 24px          <- inflated every rem by 50%
     body   font-family: Lato        <- and colour, and 24px text
     a      underline, #0270E0       <- blue underlined links everywhere
     h1-h6  Merriweather, bold
     button brown fill, 6px radius, 22px text

   The 24px root was the worst of it: it broke the type scale and pushed the
   header nav 152px past the viewport.

   Two defences, because either alone is brittle:
     1. fields.json defaults now describe the Glow system, so the generated CSS
        mostly agrees rather than fights.
     2. This layer re-asserts the essentials one specificity step higher
        (`:root` over `html`, `html body` over `body`, `html a` over `a`) so a
        theme setting changed in the HubSpot UI can never silently wreck the
        design again.

   Specificity, not !important — these need to stay overridable by real
   component rules.
   ========================================================================== */

/* Root — the critical one. `:root` is (0,1,0) and beats `html` at (0,0,1). */
:root {
  font-size: 100%;
}

html body {
  font-family: var(--glow-font-body);
  font-size: var(--glow-body);
  font-weight: 400;
  line-height: 1.7;
  color: var(--glow-ink-soft);
  background: var(--glow-cream);
}

/* Links — kill the injected underline and blue. Components restore any
   decoration they want (.glow-availability keeps its border-bottom rule). */
html a,
html a:hover,
html a:focus,
html a:active {
  color: inherit;
  font-family: inherit;
  font-weight: inherit;
  text-decoration: none;
}

/* Display type */
html h1, html h2, html h3, html h4 {
  font-family: var(--glow-font-display);
  font-weight: 400;
  color: var(--glow-ink);
  letter-spacing: -0.015em;
  line-height: 1.06;
  text-transform: none;
}

html h1 { font-size: var(--glow-h1); }
html h2 { font-size: var(--glow-h2); line-height: 1.1; }
html h3 { font-size: var(--glow-h3); line-height: 1.25; letter-spacing: -0.005em; }
html h4 { font-size: 1.25rem; line-height: 1.3; }

html p {
  font-family: var(--glow-font-body);
  font-weight: 400;
  text-decoration: none;
}

/* Our own button must not inherit the theme's brown fill and 6px radius. */
html .glow-button {
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
  font-weight: 500;
  text-transform: none;
  color: var(--glow-cream);
  background-color: var(--glow-burgundy);
  border: 1px solid var(--glow-burgundy);
  border-radius: 999px;
  padding: 0.9rem 1.75rem;
}

html .glow-button:hover,
html .glow-button:focus-visible {
  color: var(--glow-cream);
  background-color: var(--glow-deep);
  border-color: var(--glow-deep);
}

html .glow-button--outline {
  color: var(--glow-ink);
  background-color: transparent;
  border-color: var(--glow-border);
}

html .glow-button--outline:hover,
html .glow-button--outline:focus-visible {
  background-color: var(--glow-blush);
}

/* Form controls on /contact — the theme styles inputs too. */
html .glow-form input,
html .glow-form textarea {
  font-family: var(--glow-font-body);
  font-size: var(--glow-small);
}

/* ---- Membership forms ------------------------------------------------------
   CAUTION: HubL is parsed INSIDE CSS COMMENTS. This file is included into
   main.css, which HubSpot renders through Jinjava, so a HubL tag written in a
   comment here is still executed — naming the passwordless tag in braces failed
   the upload with "Unknown tag". Refer to HubL tags by name only, never in
   their delimiters, anywhere in this stylesheet.

   HubSpot's injected settings CSS paints a background on the <form> elements
   that the member_login and passwordless auth tags emit — measured at
   rgb(116,106,100), a grey-brown. Inside the cream auth card that renders as a
   slab behind the fields, and it makes the real <label> elements (which DO
   exist: "Email*", "Password*") invisible, because --glow-muted sits within a
   few points of it. It reads as "placeholders only, no labels" — the exact
   defect the rebuilt screens were meant to remove.

   The form is a layout element here, not a surface. Nothing about it should
   paint. Scoped under .glow-auth so no other HubSpot form is affected. */
html .glow-auth form,
html .glow-auth #hs-membership-form,
html .glow-auth #hs-membership-passwordless-auth-form {
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
}

/* asset-bundle touch 1785734133 — see notes: HubSpot regenerates template_main.min.css
   from main.css, and editing an INCLUDED partial does not always bump the
   bundle version. Editing main.css itself does. */

/* bundle touch 1785734258 */

/* bundle touch 1785735108 */

/* bundle touch 1785735630 */

/* bundle touch 1785736172 */

/* bundle touch 1785736254 */

/* bundle touch 1785736381 */

/* bundle touch 1785736860 */

/* bundle touch 1785736923 */

/* bundle touch 1785737180 */

/* bundle touch 1785737338 */

/* bundle touch 1785737483 */

/* bundle touch 1785737608 */

/* bundle touch 1785751291 */

/* bundle touch 1785751449 */

/* bundle touch 1785752566 */

/* bundle touch 1785752831 */