/*
Framework: none (was Bootstrap-sass; replaced by hand-written native CSS)
Code Style: http://codeguide.co/#css
*/

/* Fonts are loaded via <link> in layouts/base.njk, not @import. An @import
   here is render-blocking and cannot start downloading until this stylesheet
   itself has parsed, which serialises two round-trips before any text paints. */

/* ==========================================================================
   Variables
   ========================================================================== */

:root {
  --max-width: 1200px;

  /* ------------------------------------------------------------------
     COLOR — single source of truth for the whole site.

     Names describe ROLE, not hue, so they stay honest when the scheme
     changes: a variable called --color-accent can hold anything, while
     one called --color-bright-red becomes a lie the moment it's green.

     The animated SVG backdrops read these same values at runtime (see
     src/scripts/custom-svg.js), so there is nothing to keep in sync by
     hand. Change a value here and the entire site follows, canvas
     graphics included.

     This palette is the one explored under the working name "quiet":
     near-monochrome with a single saturated accent, so the work carries
     the page rather than the colour scheme. The navy/cream/orange the
     site used from 2014 is preserved as ?theme=classic.

     To try a whole scheme, see the [data-theme] blocks below.
     ------------------------------------------------------------------ */

  /* Surfaces */
  --color-surface:        #FFFFFF;   /* default page background          */
  --color-surface-warm:   #F2F0EC;   /* About section                    */
  --color-surface-muted:  #F0F0F0;   /* light project-detail band        */
  --color-surface-dark:   #3A3A3A;   /* dark project-detail band         */

  /* Ink — dark text, and the dark surfaces that invert it */
  --color-ink:            #111111;   /* headline text, header/footer bg  */
  --color-text-base:      #2E2E2E;   /* body default                     */
  /* #767676 rather than a lighter gray: this is the lightest neutral that
     still clears WCAG AA (4.5:1) on white. The previous value read at
     2.8:1, which failed even the large-text threshold — a gap the site
     carried since 2014 and which a near-monochrome palette leans on more
     heavily, since gray is doing more of the hierarchy work. */
  --color-text-muted:     #767676;   /* client/date meta                 */

  /* Text sitting ON a dark surface or a banner photo. Deliberately NOT
     the same token as --color-surface, even though both are white today:
     in a dark scheme the page surface goes dark while this must stay
     light, so collapsing them would break one or the other. */
  --color-text-inverse:   #fff;

  /* Accent */
  --color-accent:         #B23A2F;   /* Contact section, links, headings */
  --color-accent-deep:    #8C2C23;   /* form field backgrounds           */
  --color-accent-cool:    #2E2E2E;   /* the one cool project band        */

  /* Generic anchor colour, inherited from Bootstrap. Near-inert in
     practice — nav links, social icons and buttons all set their own
     colour — but kept in the palette so no colour lives outside it. */
  --color-link:           #428bca;
  --color-link-hover:     #2a6496;

  /* Decorative backdrops — the animated rings drawn by Snap.svg.
     Previously hardcoded inside custom-svg.js, invisible to CSS. */
  --color-backdrop-1:     #0E0E0E;   /* header ring, innermost           */
  --color-backdrop-2:     #171717;   /* header ring, middle              */
  --color-backdrop-3:     #202020;   /* header ring, outermost           */
  --color-backdrop-warm:  #E2DFD8;   /* About ring                       */

  --shadow-button: 0px 1px 1px 1px rgba(0, 0, 0, 0.20);
  --shadow-button-active: 0px 3px 3px 1px rgba(0, 0, 0, 0.20);

  /* Two roles. Display is the serif voice — project titles, case-study
     section headings, and the contact block's name. Body is everything
     else, including all UI: nav, buttons, form fields, subtitles and the
     client/date meta. Serifs read poorly as interface labels, so UI stays
     sans deliberately.
     To try a serif for long-form reading later, point the body copy
     selectors at a separate --font-reading rather than changing this. */
  --font-display: 'Fraunces', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif;

  /* Type scale — a major third (1.250) from an 18px base.
     Replaces the twelve ad-hoc sizes (10/12/13/14/16/18/20/22/24/30/34/36)
     the site inherited from Bootstrap 3 and then drifted from.

     In rem, against `html { font-size: 100% }`, so the whole scale moves
     with a reader's own browser font-size setting. Every value below is
     exact — no repeating decimals — because 16 divides the scale cleanly.

     Sizes under 20px keep a half-pixel so the ratio stays honest; above
     that they round to whole pixels (largest drift, at --text-xl, is 0.4%).

     Steps are mapped by ROLE, not by nearest number. Reading copy sits at
     --text-base; UI chrome sits a step below it at --text-sm. Mapping
     numerically instead would have pulled the 16px reading paragraphs down
     to 14.5px, which is the opposite of what an 18px base is for. */
  --text-xs:   0.71875rem;  /* 11.5px  — step -2  h6                        */
  --text-sm:   0.90625rem;  /* 14.5px  — step -1  UI, nav, meta, body       */
  --text-base: 1.125rem;    /*   18px  — step  0  reading copy, buttons     */
  --text-lg:   1.375rem;    /*   22px  — step +1  h3, project + mobile nav  */
  --text-xl:   1.75rem;     /*   28px  — step +2  h2, "view project"        */
  --text-2xl:  2.1875rem;   /*   35px  — step +3  h1, contact form title    */
  --text-3xl:  2.75rem;     /*   44px  — step +4  unused; headroom          */

  --z1: 100;
  --z2: 200;
  --z3: 300;
  --z4: 400;
  --z5: 500;
}

/* ==========================================================================
   Alternate schemes — for trying color directions

   Each block re-points the SAME role tokens, so everything follows at
   once: sections, type, buttons, form fields, and the animated SVG
   backdrops (those read these values at runtime).

   To try one:
     • add ?theme=classic to any URL, or
     • in the console: document.documentElement.dataset.theme = 'dusk'
     • back to default: delete document.documentElement.dataset.theme

   Nothing here is wired into the shipped design — the default :root
   palette above is what renders unless a theme is explicitly asked for.
   ========================================================================== */

/* The palette the site shipped with from 2014 until this change: navy,
   cream and orange. Kept so the previous look is one URL away for
   comparison — ?theme=classic — not because anything still depends on it. */
:root[data-theme="classic"] {
  --color-surface:        #fff;
  --color-surface-warm:   #FAE7C9;
  --color-surface-muted:  #EDEDED;
  --color-surface-dark:   #4A4A4A;

  --color-ink:            #0D1316;
  --color-text-base:      #333333;
  --color-text-muted:     #9B9B9B;

  --color-accent:         #DC4601;
  --color-accent-deep:    #B23800;
  --color-accent-cool:    #043963;

  --color-backdrop-1:     #091928;
  --color-backdrop-2:     #0c2033;
  --color-backdrop-3:     #0d273e;
  --color-backdrop-warm:  #f8daaa;
}

/* Warmer and earthier. Espresso instead of navy, sand instead of cream,
   a burnt orange that sits closer to terracotta than the current red. */
:root[data-theme="ember"] {
  --color-surface:        #FFFCF8;
  --color-surface-warm:   #EFDFC8;
  --color-surface-muted:  #EDE7E0;
  --color-surface-dark:   #4A423B;

  --color-ink:            #1A1512;
  --color-text-base:      #2C2622;
  --color-text-muted:     #9C918A;

  --color-accent:         #C2410C;
  --color-accent-deep:    #9A3412;
  --color-accent-cool:    #3F4A2E;

  --color-backdrop-1:     #16110E;
  --color-backdrop-2:     #211913;
  --color-backdrop-3:     #2C211A;
  --color-backdrop-warm:  #E4CBA4;
}

/* Cooler and quieter. Deep slate base, pale blue-gray surfaces, and a
   muted amber accent so the Contact block reads warm without shouting. */
:root[data-theme="dusk"] {
  --color-surface:        #FDFDFD;
  --color-surface-warm:   #DCE4E8;
  --color-surface-muted:  #E9EDEF;
  --color-surface-dark:   #3D474D;

  --color-ink:            #0E1418;
  --color-text-base:      #29323A;
  --color-text-muted:     #8B959C;

  --color-accent:         #C2610C;
  --color-accent-deep:    #96490A;
  --color-accent-cool:    #12414F;

  --color-backdrop-1:     #0B1418;
  --color-backdrop-2:     #101E26;
  --color-backdrop-3:     #152833;
  --color-backdrop-warm:  #CFE0E6;
}

/* ==========================================================================
   Base layer

   This replaces the parts of Bootstrap's normalize + scaffolding + type
   layers that the site actually depends on. Do not trim this section
   thinking it's boilerplate — every rule here is load-bearing, verified
   against docs/superpowers/reference/compiled-main.css:

   - `box-sizing: border-box` is what makes every percentage-width column
     in Tasks 9-10 line up, since they all also carry 15px side padding.
     Without it the entire grid math is wrong.
   - The body font-size/line-height/color are inherited by all copy.
   - The heading margins/sizes are relied on by .project-title (h2),
     .project-subtitle (h3), and every h3/h4/h5/h6 inside the project
     detail pages, which set colors but not sizes or spacing.
   - `p { margin: 0 0 10px }` spaces all body copy.
   - `button, input, textarea { font: inherit }` is what makes the form
     controls and the nav/close buttons pick up the body font instead of
     the browser's default form font.
   ========================================================================== */

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

html {
  font-family: sans-serif;
  /* Was 10px — Bootstrap 3's trick for making rem math tidy (1rem = 10px).
     It was inert here: nothing on the site used rem, and `body` immediately
     overrode the inherited size. Now that the type scale IS in rem, this has
     to be 100% so a step resolves against the reader's browser font-size
     rather than a hardcoded 10px, which would render the whole site at 62.5%
     of its intended size. */
  font-size: 100%;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

body {
  margin: 0;
  /* The document default, which is UI chrome rather than reading size —
     long-form copy opts up to --text-base at its own selectors. */
  font-size: var(--text-sm);
  line-height: 1.428571429;
  color: var(--color-text-base);
  background-color: var(--color-surface);
  padding-top: 0px;
  padding-bottom: 0;
  font-family: var(--font-body);
}

h1, h2, h3, h4, h5, h6 {
  font-family: inherit;
  font-weight: 500;
  line-height: 1.1;
  color: inherit;
}

h1, h2, h3 {
  margin-top: 20px;
  margin-bottom: 10px;
}

h4, h5, h6 {
  margin-top: 10px;
  margin-bottom: 10px;
}

h1 { font-size: var(--text-2xl); }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
h4 { font-size: var(--text-base); }
h5 { font-size: var(--text-sm); }
h6 { font-size: var(--text-xs); }

p {
  margin: 0 0 10px;
}

a {
  background: transparent;
  color: var(--color-link);
  text-decoration: none;
}

a:hover,
a:focus {
  color: var(--color-link-hover);
  text-decoration: underline;
}

a:focus {
  outline: thin dotted;
  outline: 5px auto -webkit-focus-ring-color;
  outline-offset: -2px;
}

a:hover {
  outline: 0;
}

img {
  border: 0;
  vertical-align: middle;

  /* Production's <img> tags carry no width/height attributes, so their
     height has always come from the aspect ratio. eleventy-img (Task 11)
     DOES emit width/height — good, it reserves space and prevents layout
     shift — but without `height: auto` the height attribute becomes the
     used height and images render at their intrinsic height regardless of
     how CSS sized their width. `.img-responsive` already carries this;
     `.img-work` does not, which is how it surfaced. Setting it globally
     matches production behavior for every image. */
  height: auto;
}

button,
input,
optgroup,
select,
textarea {
  color: inherit;
  font: inherit;
  margin: 0;
}

button {
  overflow: visible;
  text-transform: none;
}

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

input {
  line-height: normal;
}

textarea {
  overflow: auto;
}

/* eleventy-img (Task 11) emits <picture><img …></picture> when it outputs
   more than one format. `display: contents` removes the <picture> box from
   layout so the inner <img> participates in its parent's layout directly —
   without this, `.center-block`'s `display:block; margin:auto` centering
   breaks, because the inline <picture> wrapper would be what's laid out. */
picture {
  display: contents;
}

/* Legacy IE<10 upgrade notice. Deliberately left outside the palette —
   it renders only on browsers that predate CSS custom properties. */
.browsehappy {
  margin: 0.2em 0;
  background: #ccc;
  color: #000;
  padding: 0.2em 0;
}

.container-fluid {
  margin-right: auto;
  margin-left: auto;
  padding-left: 0px;
  padding-right: 0px;
}

.container-fluid::before,
.container-fluid::after {
  content: " ";
  display: table;
}

.container-fluid::after {
  clear: both;
}

.img-responsive {
  display: inline-block;
  max-width: 100%;
  height: auto;
}

.center-block {
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
}

/* ==========================================================================
   Header / intro
   ========================================================================== */

.header {
  position: relative;
  height: 100vh;
  z-index: var(--z1);
  text-align: center;
  color: var(--color-surface);
  background-color: var(--color-ink);
  font-weight: bold;
}

.intro-title {
  position: relative;
  margin-top: 0;
  margin-bottom: 0;
  padding-top: 30px;
  font-size: var(--text-sm);
  z-index: var(--z1);
  padding-left: 25%;
  padding-right: 25%;
  line-height: 140%;
}

@media (min-width: 480px) { /* was $screen-xs-min */
  .intro-title {
    font-size: var(--text-base);
    padding-top: 40px;
    padding-left: 0;
    padding-right: 0;
    line-height: 100%;
  }
}

.svg-container {
  position: absolute;
  height: 100%;
  width: 100%;
  vertical-align: middle;
  overflow: hidden;
}

.svg-container::before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */
}

.head-spin {
  height: 100%;
  width: 99%;
  top: 0;
  left: 0;
  vertical-align: middle;
}

/* .intro-inner-container uses Sass `@extend .container`, but in PRODUCTION
   that extend never reached Bootstrap's width-stepping @media blocks: the
   live stylesheet's `@media (min-width:768px){.container{width:750px}}`
   rules list `.container` alone. node-sass did not propagate @extend into
   media queries; Dart Sass does, which is why the regenerated reference
   file shows all four extended selectors there and is misleading here.
   (This is the same mechanism behind the full-width Work-section bug fixed
   earlier in this project's history.)

   So production renders this element FLUID — centered, no width ladder —
   capped only by its own max-width:1024px from 768px up. Verified against
   the live stylesheet. Do not add width: 750/970/1170 rules here; an
   earlier draft of this plan did, which made the intro narrower than
   production everywhere between 768px and 1200px. */
.intro-inner-container {
  position: relative;
  height: 100%;
  z-index: var(--z2);
  margin-top: -40px;
  padding-left: 0px;
  padding-right: 0px;
  margin-right: auto;
  margin-left: auto;
}

.intro-inner-container::before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */
}

@media (min-width: 480px) { /* was $screen-xs-min */
  .intro-inner-container {
    margin-top: -20px;
  }
}

@media (min-width: 768px) { /* was $screen-sm-min */
  .intro-inner-container {
    max-width: 1024px;
  }
}

/* The signature is an inline <svg> (see index.njk), not an <img>, so that
   `currentColor` picks up the palette below and follows the [data-theme]
   schemes with everything else. The PNG it replaced was baked in the 2014
   orange (#D24301) and could never do that.

   Colour: the header sits on --color-ink (#111), where --color-accent
   measures about 2.5:1 — under AA even for large text. --color-text-inverse
   is 18.9:1 there. To try the mark in another colour, change this one
   declaration; nothing else needs to move.

   Width, not height: an explicit width with `height: auto` lets the
   viewBox (539x681) drive the box, so there is no aspect-ratio to keep in
   sync. 380px at desktop matches the height the old 434x480 PNG rendered
   at, which keeps the header's vertical rhythm — the new mark is a
   narrower, taller composition, so matching width instead would have made
   the header ~70px taller. */
#introImg {
  display: inline-block;
  vertical-align: middle;
  width: 60%;
  height: auto;
  color: var(--color-text-inverse);
}

@media (min-width: 768px) { /* was $screen-sm-min */
  #introImg {
    width: 380px;
  }
}

/* The three section marks, same deal as the signature: inline <svg> drawn
   with currentColor, so one declaration each sets the colour and the
   [data-theme] schemes come along for free.

     About   ink on --color-surface-warm  (#111 on #F2F0EC, 16.6:1)
     Work    ink on --color-surface-warm  (#111 on #F2F0EC, 16.6:1)
     Contact inverse on --color-accent    (#fff on #B23A2F,  5.9:1)

   About and Work deliberately match. They sit on the same warm surface and
   do the same job — naming a section — so colouring them differently would
   imply a distinction that isn't there. Work was accent while its section
   was still on white, where the surface change carried the difference; once
   Work moved to the warm surface that reason went away.

   Keeping the accent off these also protects what it signals. It already
   carries the Contact block, case-study h3s and nav hover, and the
   near-monochrome palette depends on the full-bleed Contact block being the
   one chromatic event as you scroll. Ink is also the quieter neighbour for
   the project banners directly below, which are full-colour photography.

   Sizing stays exactly where it was (.img-about / .img-work / .img-contact
   further down). Note the new marks are squarer than the PNGs they replace,
   so at the same width they stand taller — Contact by ~43%, Work by ~23%.
   That is a property of the new artwork, not of this rule. */
.img-about   { color: var(--color-ink); }
.img-work    { color: var(--color-ink); }
.img-contact { color: var(--color-text-inverse); }

/* ==========================================================================
   Nav / collapse — the Bootstrap-derived rules that vendor/bootstrap/
   collapse.js needs to function (toggling the .in class), plus the site's
   own overrides. This is a small, deliberate slice of Bootstrap's navbar
   component, not the whole thing.
   ========================================================================== */

.collapse {
  display: none;
}

.collapse.in {
  display: block;
}

.collapsing {
  position: relative;
  height: 0;
  overflow: hidden;
  transition: height 0.35s ease;
}

.nav {
  margin-bottom: 0;
  padding-left: 0;
  list-style: none;
}

.nav > li > a {
  position: relative;
  display: block;
  padding: 10px 15px;
  font-size: var(--text-sm);
  padding-left: 5px;
  padding-right: 5px;
}

@media (min-width: 480px) { /* was $screen-xs-min */
  .nav > li > a {
    /* The 13px -> 14px bump that used to live here is gone: both ends of it
       now resolve to --text-sm, so it had become a no-op. The padding change
       is the real content of this breakpoint. */
    padding-left: 15px;
    padding-right: 15px;
  }
}

/* `text-decoration: none` on hover/focus comes from Bootstrap's own
   `.nav > li > a:hover, :focus` rule. It must be carried over explicitly —
   the base layer's `a:hover { text-decoration: underline }` would
   otherwise underline every nav link on hover, which the live site
   does not do. */
.nav > li > a:hover,
.nav > li > a:focus {
  text-decoration: none;
}

.nav > li > a:visited,
.nav > li > a:focus {
  background-color: transparent;
  color: var(--color-text-inverse);
}

.nav > li > a:hover {
  background-color: transparent;
  color: var(--color-accent);
}

.nav > li > a:active {
  background-color: transparent;
  color: var(--color-ink);
}

.navbar {
  position: relative;
  border: 1px solid transparent;
  margin-bottom: 20px;
  top: -100px;
  min-height: 120px;
  z-index: var(--z2);
}

.navbar-collapse {
  overflow-x: visible;
  padding-right: 15px;
  padding-left: 15px;
  border-top: 1px solid transparent;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);
}

.navbar-collapse::before,
.navbar-collapse::after {
  content: " ";
  display: table;
}

.navbar-collapse::after {
  clear: both;
}

.navbar-nav {
  margin: 7.5px -15px;
  float: none;
  text-align: center;
  margin-left: 0;
  margin-right: 0;
}

.navbar-nav > li {
  float: none;
  display: inline-block;

  & > a {
    padding-top: 10px;
    padding-bottom: 10px;
    line-height: 20px;
    display: inline-block;
    color: var(--color-surface);

    /* Bootstrap bumps this to 15px at desktop and nothing in main.scss
       overrides it, so production's desktop nav links are 10px taller than
       the mobile-first base. Easy to miss: it lives in Bootstrap's navbar
       layer, not in the site's own stylesheet. Verified against the live
       stylesheet. */
    @media (min-width: 768px) {
      padding-top: 15px;
      padding-bottom: 15px;
    }
  }
}

.spacey {
  padding-left: 15px;
  padding-right: 15px;
}

.navbar-toggle {
  position: fixed;
  left: 25px;
  top: 17px;
  height: 50px;
  width: 50px;
  padding: 13px;
  margin: 0 30px 30px 0;
  border-radius: 50%;
  background-color: var(--color-surface);
  border: 1px solid transparent;
  box-shadow: var(--shadow-button);
  z-index: var(--z5);

  &:hover {
    box-shadow: var(--shadow-button-active);
  }

  &:active {
    background-color: var(--color-accent);
    box-shadow: var(--shadow-button-active);
  }

  /* Bootstrap suppressed the default focus ring on this button; without it
     the round hamburger gets a browser outline on keyboard focus. */
  &:focus {
    outline: 0;
  }

  & .icon-bar {
    display: block;
    width: 22px;
    height: 3px;
    border-radius: 1px;

    & + .icon-bar {
      margin-top: 4px;
    }
  }

  & span {
    background-color: var(--color-ink);
  }
}

@media (min-width: 768px) { /* was $screen-sm-min */
  #navbar-collapse {
    display: none !important;
  }

  /* Hides the hamburger button at desktop widths. This comes from
     Bootstrap's navbar layer, not from main.scss, which is why it is easy
     to miss when porting only the site's own stylesheet — but it is
     load-bearing: without it the round hamburger stays visible on desktop,
     overlapping the page. Verified present in both the compiled reference
     and the live production stylesheet. */
  .navbar-toggle {
    display: none;
  }
}

@media (max-width: 768px) { /* was $screen-sm-min */
  .navbar-collapse {
    position: fixed;
    top: 0px;
    left: 0px;
    bottom: 0px;
    right: 0px;
    background-color: var(--color-surface);
    z-index: var(--z4);

    & ul {
      margin-top: 50%;
      text-align: center;

      & li {
        display: block;
        margin-bottom: 30px;

        & a {
          display: block;
          color: var(--color-ink);
          font-size: var(--text-lg);
          font-weight: bold;
        }
      }
    }
  }
}

/* NOTE: main.scss also had a `.nav-collapse > ul` rule (setting a 50px
   bottom margin on its list items) — omitted here. `.nav-collapse`, without
   the "navbar-" prefix, matches nothing in the markup and is referenced by
   no selector in any script; it was already dead CSS in the live site. */

/* ==========================================================================
   About
   ========================================================================== */

.section-about {
  position: relative;
  z-index: var(--z2);
  padding-top: 90px;
  padding-right: 20%;
  padding-left: 20%;
  padding-bottom: 90px;
  background-color: var(--color-surface-warm);
  color: var(--color-ink);
  overflow: hidden;
}

.about-inner-container {
  position: relative;
  text-align: center;

  /* Not `img.img-about`: the mark is an inline <svg> now, so an
     element-qualified selector would stop matching and silently drop the
     sizing. Same reason the rules at the 768px breakpoint and
     `.img-contact` further down lost their `img` qualifier. */
  & .img-about {
    width: 80%;

    @media (min-width: 480px) { /* was $screen-xs-min */
      width: 60%;
    }
  }

  & p {
    padding-top: 30px;
    font-weight: normal;
    font-size: var(--text-sm);
    line-height: 160%;
    text-align: left;

    @media (min-width: 480px) { /* was $screen-xs-min */
      font-size: var(--text-base);
    }
  }
}

img.about-headshot {
  display: none;
}

.content-row {
  margin-left: -15px;
  margin-right: -15px;
}

.content-row::before,
.content-row::after {
  content: " ";
  display: table;
}

.content-row::after {
  clear: both;
}

/* .text-holder-offset replaces Bootstrap's
   make-sm-column(5) + make-md-column(4) + make-sm-column-offset(3) */
.text-holder-offset {
  position: relative;
  min-height: 1px;
  padding-left: 15px;
  padding-right: 15px;
  z-index: var(--z1);
}

@media (min-width: 768px) { /* was $screen-sm-min */
  .text-holder-offset {
    float: left;
    width: 41.6666666667%;
    margin-left: 25%;
  }
}

@media (min-width: 992px) { /* was $screen-md-min */
  .text-holder-offset {
    width: 33.3333333333%;
  }
}

/* .img-holder-4 replaces make-sm-column(4) */
.img-holder-4 {
  position: relative;
  min-height: 1px;
  padding-left: 15px;
  padding-right: 60px;
  margin-top: -70px;
  margin-bottom: 70px;
}

@media (min-width: 768px) { /* was $screen-sm-min */
  .img-holder-4 {
    float: left;
    width: 33.3333333333%;
  }
}

.svg-container-about {
  display: none;
  position: absolute;
  height: 100%;
  width: 100%;
  vertical-align: middle;
  overflow: visible;
}

.svg-container-about::before {
  content: '';
  display: inline-block;
  height: 100%;
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */
}

.head-spin-about {
  display: none;
  height: 100%;
  width: 99%;
  top: 0;
  left: 0;
  vertical-align: middle;
  overflow: visible !important;
}

@media (min-width: 768px) { /* was $screen-sm-min — NOT screen-md-min, verify against source line 432 if in doubt */
  .svg-container-about,
  .head-spin-about {
    display: inline-block;
  }
  .section-about {
    padding-right: 0;
    padding-left: 0;
  }
  .about-inner-container {
    max-width: var(--max-width);
    margin: auto;
    text-align: left;
  }
  .about-inner-container .img-about {
    width: 40%;
    max-width: 400px;
    margin-left: 6%;
  }
  .about-inner-container img.about-headshot {
    position: relative;
    display: inline-block;
  }
  .text-holder-offset {
    margin-top: -90px;
  }
}

/* ==========================================================================
   Work
   ========================================================================== */

.section-work {
  position: relative;
  z-index: var(--z1);
  padding-top: 90px;
  padding-bottom: 0px;
  padding-right: 0px;
  padding-left: 0px;
  background-color: var(--color-surface-warm);
  color: var(--color-ink);
  overflow: hidden;
}

/* .work-inner-container: deliberately full-width (not the Bootstrap
   .container behavior .intro-inner-container/.contact-inner-container get)
   — see the design spec's CSS section for why this was made explicit
   rather than left to an @extend that silently didn't apply at some
   breakpoints under the old Sass engine. That was a real bug, fixed
   earlier in this project's history. */
.work-inner-container {
  position: relative;
  width: 100%;
  padding-right: 0px;
  padding-left: 0px;
  min-height: 1200px;
}

.work-lead-in {
  position: relative;
  z-index: var(--z2);
  padding-top: 0px;
  padding-right: 20%;
  padding-left: 20%;
  padding-bottom: 90px;
  font-size: var(--text-base);
  line-height: 160%;
  text-align: center;
  max-width: var(--max-width);
  margin: auto;

  @media (min-width: 480px) { /* was $screen-xs-min */
    font-size: var(--text-base);
    line-height: 140%;
    padding-top: 20px;
    padding-bottom: 90px;
  }
}

.img-work {
  width: 60%;
  padding-bottom: 20px;
  max-width: 400px;
  /* `.img-responsive` carries height:auto and the global `img` rule used to
     supply it otherwise — but this mark is an <svg> and does not use
     .img-responsive, so it needs its own. Without it the viewBox height is
     the used height and the mark renders at intrinsic size. */
  height: auto;
}

@media (min-width: 480px) { /* was $screen-xs-min */
  .img-work {
    width: 40%;
  }
}

/* Banner height. The order of these two rules matters and is NOT the order
   the Dart Sass reference emits them in — see the correction note below.
   Live production serves the unconditional 406px FIRST and the max-width
   override SECOND, so banners really are 250px tall at <=768px. Verified by
   measuring both sites at a 500px viewport: live 250px, and this port must
   match. Do not reorder these. */
.project-banner {
  height: 406px;
  text-align: center;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
  overflow: hidden;
}

@media (max-width: 768px) {
  .project-banner {
    height: 250px;
  }
}

.is_stuck {
  z-index: var(--z4);
}

.project-return { 
  height: 0;
  overflow: hidden;
}

.project-validic { background-image: url(/images/banner-mobile-validic.jpg); }
.project-hillrom { background-image: url(/images/banner-mobile-hillrom.jpg); }
.project-ssa { background-image: url(/images/banner-mobile-ssa.jpg); }
.project-artistprofile { background-image: url(/images/banner-mobile-artistprofile.jpg); }

.project-title {
  position: relative;
  margin-bottom: 0px;
  padding-left: 15px;
  padding-right: 15px;
  /* Mobile-first: one step down from the size these run at on wider
     screens. See the @media block below for why the step exists. */
  font-size: var(--text-lg);
  /* Fraunces is drawn heavier than Montserrat at the same nominal weight,
     so `bold` here would look overbearing over the banner photos. 600 is
     the visual match. */
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.004em;
  color: var(--color-text-inverse);
}

.project-subtitle {
  position: relative;
  margin-top: 7px;
  padding-left: 15px;
  padding-right: 15px;
  font-size: var(--text-sm);
  font-weight: normal;
  letter-spacing: -0.004em;
  color: var(--color-text-inverse);
}

/* Banner type steps up once there is room for it.

   This block is NOT the Bootstrap-era one that used to sit here. That one
   stepped 20 -> 24px and 13 -> 14px, and on the major-third scale both of
   its ends collapsed onto a single step, making it a no-op — so it was
   deleted. This is a deliberate replacement, and the step is real: a full
   scale step at each of the two roles.

   It exists because the banner is a fixed 250px on mobile with
   `overflow: hidden`, and the type is vertically centred inside it. At the
   wide sizes, the longest title (Hill-Rom) wraps to two lines AND its
   subtitle wraps to two, which together overflow that 250px box by 7px —
   clipping the bottom of the "+" button. Holding one step back on small
   screens keeps four pixels of headroom and stops three of the four titles
   from wrapping at all.

   The breakpoint is 769px, and it is deliberately NOT one of the site's
   usual 480/768/992 stops. It is the width at which the banner itself
   grows from 250px to 406px, so the type steps up exactly when its
   container does. Note that boundary is not 480px, even though a
   `@media (min-width: 480px)` rule sets `height: 406px`: a LATER
   `@media (max-width: 768px)` rule sets it back to 250px and wins through
   the whole 480-768 range. Stepping the type at 480px — which an earlier
   version of this did — put 28px titles inside a 250px banner and clipped
   Hill-Rom by 7px.

   Tying the two together this way means it stays correct no matter how
   long a future title is: above 769px there is ~97px of headroom even
   with a two-line title. The cost is that tablets from roughly 535px up
   could carry the larger type safely today and don't. That is a content
   measurement of one specific title rather than a structural fact, so it
   is not worth encoding. */
@media (min-width: 769px) {
  .project-title {
    font-size: var(--text-xl);
  }
  .project-subtitle {
    font-size: var(--text-base);
  }
}

.btn-project-explode,
.btn-project-close {
  display: inline-block;
  position: relative;
  height: 100px;
  width: 100px;
  z-index: var(--z4);
  margin: 0;
  text-align: left;
  cursor: pointer;
}

.btn-project-text {
  position: absolute;
  left: 38%;
  top: 27%;
  font-size: var(--text-xl);
}

.btn-project-more,
.btn-project-next {
  height: 50px;
  width: 50px;
  margin: 0;
  padding: 0;
  background-color: var(--color-surface);
  border-radius: 50%;
  border: none;
  z-index: var(--z5);
  font-size: var(--text-base);
  font-weight: bold;
  text-transform: uppercase;
  box-shadow: var(--shadow-button);
  color: var(--color-ink);
  cursor: pointer;
}

.btn-project-next {
  margin-bottom: 40px;
}

@media (min-width: 480px) { /* was $screen-xs-min */
  .btn-project-text {
    left: 40%;
    top: 29%;
  }
  .btn-project-more {
    font-size: var(--text-base);
  }
}

.btn-project-close {
  position: fixed;
  top: -50px;
}

/* NOTE: also dead code, preserved for the same reason as the
   .project-banner rule above — the @media (min-width: 480px) rule further
   down always wins at any viewport where this one would apply too, since
   it comes later in the compiled cascade. Confirmed against
   .tmp/styles/main.css during planning. */
@media (min-width: 768px) {
  .btn-project-close {
    top: -100px;
  }
}

.btn-project-close {
  right: 25px;
  color: var(--color-ink);
  background-color: transparent;
  border: none;
  z-index: var(--z2);
  transform: rotate(45deg);
  outline: none;
}

@media (min-width: 480px) { /* was $screen-xs-min */
  .btn-project-close {
    top: 15px;
  }
}

.btn-project-off {
  display: none;
}

/* ==========================================================================
   Project (expanded/detail content, loaded via ajax into .project-return)
   ========================================================================== */

.project-controls {
  text-align: center;
  padding-top: 0px;
}

.project-expanded {
  & h3, & h4, & h5, & h6 {
    text-align: center;
  }

  /* Only h3 is a section heading ("UI Development", "User Research and
     Personas") and takes the display serif. h4 is a descriptive deck and
     h5/h6 are client/date meta — those stay sans, which also gives the
     serif heading something to contrast against. */
  & h3 {
    font-family: var(--font-display);
    font-weight: 600;
  }
}

.project-expanded-section {
  /* Base margins are 0, NOT -15px. main.scss applies Bootstrap's make-row
     mixin (which sets -15px) and then explicitly resets both to 0 in the
     same rule, so 0 is what actually renders; the -15px only returns at
     >=480px via the media query at the end of this block. Verified against
     both the compiled reference and the live production stylesheet — an
     earlier draft of this plan had the base value as -15px, which rendered
     the project detail content 15px wider than production below 480px. */
  margin-left: 0;
  margin-right: 0;
  padding-top: 60px;
  padding-bottom: 60px;

  &::before,
  &::after {
    content: " ";
    display: table;
  }

  &::after {
    clear: both;
  }

  & img {
    padding-top: 60px;
  }

  & p:first-child {
    padding-top: 40px;
  }

  @media (min-width: 480px) { /* was $screen-xs-min */
    margin-left: -15px;
    margin-right: -15px;
  }
}

.project-section-white {
  background-color: var(--color-surface);

  & h3 {
    color: var(--color-accent);
    font-weight: bold;
  }
  & h4 {
    /* Was literal `black`. Every other dark text on the site is
       --color-ink (#0D1316), so this was almost certainly an oversight
       rather than a decision. Folding it in changes the rendered colour
       by an imperceptible amount and keeps the palette complete. */
    color: var(--color-ink);
  }
  & h5, & h6 {
    color: var(--color-text-muted);
    font-weight: normal;
  }
  & p {
    color: var(--color-ink);
  }
}

.project-section-gray {
  background-color: var(--color-surface-muted);

  & h3 {
    color: var(--color-accent-cool);
    font-weight: bold;
  }
}

.project-section-gray-dark {
  background-color: var(--color-surface-dark);

  & h3 {
    color: var(--color-text-inverse);
    font-weight: bold;
  }
  & p {
    color: var(--color-text-inverse);
  }
}

.project-section-red {
  background-color: var(--color-accent);

  & h3 {
    color: var(--color-text-inverse);
    font-weight: bold;
  }
  & p {
    color: var(--color-text-inverse);
  }
}

.project-section-blue {
  background-color: var(--color-accent-cool);

  & h3 {
    color: var(--color-text-inverse);
    font-weight: bold;
  }
  & p {
    color: var(--color-text-inverse);
  }
}

/* Each .project-section-* rule above sets `font-weight: bold` on its h3 for
   the old sans. Those land after the display-font rule and have equal
   specificity, so they win — which asks the browser for Fraunces 700 when
   only 600 is loaded, and it answers by synthesising a faux bold that
   smears the serif. Pin the display weight back here, after them. */
.project-expanded-section h3 {
  font-weight: 600;
}

/* .project-expanded-content replaces make-xs-column(8) + make-xs-column-offset(2) */
.project-expanded-content {
  position: relative;
  float: left;
  width: 66.6666666667%;
  min-height: 1px;
  padding-left: 15px;
  padding-right: 15px;
  margin-left: 16.6666666667%;
}

/* .project-expanded-content-wide replaces make-xs-column(10) + make-xs-column-offset(1) */
.project-expanded-content-wide {
  position: relative;
  float: left;
  width: 83.3333333333%;
  min-height: 1px;
  padding-left: 15px;
  padding-right: 15px;
  margin-left: 8.3333333333%;
  text-align: center;
}

.project-expanded-text-only {
  padding-top: 0px;
  padding-bottom: 25px;
  line-height: 160%;
  font-size: var(--text-base);
  font-weight: 300;
}

/* ==========================================================================
   Contact
   ========================================================================== */

.section-contact {
  position: relative;
  z-index: var(--z1);
  padding: 90px 0;
  background-color: var(--color-accent);
  /* Text on this block is inverse, not ink. Near-black on a saturated
     accent measured 3.2:1 — under AA for the 13px copy and 16px subtitle
     that live here, neither of which is large enough to be exempt. */
  color: var(--color-text-inverse);
  overflow: hidden;
}

/* Same story as .intro-inner-container: the Sass `@extend .container` never
   reached Bootstrap's width-stepping @media blocks in production, because
   node-sass did not propagate @extend into media queries (Dart Sass does,
   so the regenerated reference file is misleading here — check the live
   stylesheet instead). Production renders this FLUID, centered, capped only
   by its own max-width:1200px from 480px up — and that cap is NOT a no-op:
   it is what actually constrains the Contact section on wide screens.
   Do not add width: 750/970/1170 rules here; an earlier draft of this plan
   did, which made the whole Contact section narrower than production at
   every width from 768px up (30px too narrow at >=1200px). */
.contact-inner-container {
  position: relative;
  text-align: center;
  margin-right: auto;
  margin-left: auto;
  padding-left: 15px;
  padding-right: 15px;

  &::before,
  &::after {
    content: " ";
    display: table;
  }

  &::after {
    clear: both;
  }

  & p {
    position: relative;
    padding-top: 20px;
    font-weight: normal;
    font-size: var(--text-sm);
    line-height: 160%;
    text-align: left;
  }
}

@media (min-width: 480px) { /* was $screen-xs-min */
  .contact-inner-container {
    max-width: 1200px;
    text-align: left;
    padding-left: 40px;
    padding-right: 40px;
  }
  .contact-inner-container p {
    font-size: var(--text-base);
  }
  .contact-form-wrapper {
    text-align: center;
  }
}

.contact-social-icons {
  display: table;
  width: 100%;
  text-align: center;
  margin-top: 40px;
  margin-bottom: 40px;

  & a[role="social"] {
    display: table-cell;
  }
}

.img-contact {
  padding-bottom: 30px;
  width: 100%;
  padding-left: 15%;
  padding-right: 15%;
}

.contact-copy {
  padding-left: 10%;
  padding-right: 10%;
}

.svg-icon {
  width: 40%;
  fill: var(--color-text-inverse);
}

.svg-icon:hover {
  fill: var(--color-surface-warm);
}

.contact-form-title {
  padding-top: 0px;
  margin-top: 0px;
  margin-bottom: 0px;
  font-size: var(--text-2xl);
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.3em;
}

.contact-form-subtitle {
  padding-top: 0px;
  margin-top: 0px;
  font-size: var(--text-base);
  font-weight: bold;
}

.contact-form-wrapper {
  padding: 20px;
  text-align: center;
  box-shadow: 0px 2px 4px 0px rgba(0,0,0,0.50);
}

/* Intentionally omitted from this port, all confirmed dead:
   - `.contact-info`, `#contactSpinner`, `#contactSpinnerParent` (+ its
     `:hover`) — the email/phone list and spinner graphic these styled were
     already removed from the markup (see the committed contact-info removal
     that index.njk was ported from).
   - `@keyframes spin` / `@keyframes backspin` — only ever referenced by the
     two spinner rules above, so they go with them.
   - `.declaration-order` — never a real style; it was a CSS-property-order
     style guide crib note left at the top of main.scss, matching no markup.
   If the spinner is ever reinstated, all of the above are recoverable from
   git history (app/styles/main.scss). */

/* ==========================================================================
   Row / col-sm-6 (used by the Contact section's two-column layout)
   ========================================================================== */

.row {
  margin-left: -15px;
  margin-right: -15px;
}

.row::before,
.row::after {
  content: " ";
  display: table;
}

.row::after {
  clear: both;
}

.col-sm-6 {
  position: relative;
  min-height: 1px;
  padding-left: 15px;
  padding-right: 15px;
}

@media (min-width: 768px) { /* was $screen-sm-min */
  .col-sm-6 {
    float: left;
    width: 50%;
  }
}

/* ==========================================================================
   Form
   ========================================================================== */

#form-div {
  position: relative;
}

.feedback-input {
  /* 2.2:1 as ink on the deep-accent field. This is the text a visitor
     types, so it has to be readable. On focus the field turns light and
     the rule below correctly switches back to ink. */
  color: var(--color-text-inverse);
  border: none;
  background-color: var(--color-accent-deep);
  padding: 15px 13px 15px 13px;
  margin-bottom: 30px;
  width: 100%;
  box-shadow: inset 0px 2px 4px 0px rgba(0,0,0,0.26);
}

.feedback-input:focus {
  background: var(--color-surface-warm);
  /* `box-shadow: 0` is invalid CSS — copied verbatim from main.scss on
     purpose. Browsers discard the declaration, so the focused input keeps
     the inset shadow inherited from .feedback-input above. "Correcting"
     this to `none` would remove that shadow on focus, i.e. it would be a
     real visual change, not a cleanup. Leave it alone. */
  box-shadow: 0;
  border: none;
  color: var(--color-ink);
  outline: none;
}

textarea {
  width: 100%;
  height: 150px;
  line-height: 150%;
  resize: vertical;
}

input:hover, textarea:hover,
input:focus, textarea:focus {
  background-color: var(--color-surface-warm);
}

/* Placeholders were --color-accent on the deep-accent field: 1.4:1, which
   is effectively invisible. */
::-webkit-input-placeholder {
  color: var(--color-text-inverse);
  font-weight: bold;
}

::-moz-placeholder {
  color: var(--color-text-inverse);
  font-weight: bold;
}

:-ms-input-placeholder {
  color: var(--color-text-inverse);
  font-weight: bold;
}

#button-submit {
  width: 100%;
  border: none;
  cursor: pointer;
  background-color: var(--color-ink);
  color: var(--color-text-inverse);
  font-size: var(--text-base);
  padding-top: 15px;
  padding-bottom: 15px;
  box-shadow: var(--shadow-button);
}

#form-messages {
  margin-top: 20px;
}

#button-submit:hover {
  color: var(--color-ink);
  background-color: var(--color-surface-warm);
}

#button-submit:active {
  background-color: var(--color-accent);
}

/* ==========================================================================
   State
   ========================================================================== */

.mob-verticalAdjust {
  position: relative;
  top: 50%;
  transform: translateY(25%);
}

.mob-verticalAdjustCenter {
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}
