@charset "utf-8";

/* ==========================================================================
   Rock Island Boat Club
   Layout is CSS Grid throughout. There is no Flexbox in this file.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Color */
  --navy-deep:    #1F3A63;  /* nav text and rules, Join Us band, footer, card titles */
  --navy-ink:     #3A3A38;  /* body copy on light backgrounds */
  --cream:        #FCEBCF;  /* every light band, and the nav bar */
  --periwinkle:   #8FA8D0;  /* location band and the info cards */
  --white-soft:   #FDF6EA;  /* text on navy, button fill on navy */

  /* Bronze. Split into three because one value cannot clear the contrast floor
     in all three roles on --cream:
       --bronze      3.8:1  section titles and the price figure only, all of
                            which are >=24px, where the floor is 3:1
       --bronze-ink  4.6:1  smaller bronze text such as "Half Day"
       --bronze-fill 4.7:1  button fill carrying a --white-soft label       */
  --bronze:       #8C7350;
  --bronze-ink:   #7E6544;
  --bronze-fill:  #7A6A54;

  /* Type */
  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-body:    "Lora", Georgia, serif;

  /* Rhythm */
  --section-y:    5.5rem;   /* vertical padding on every band */
  --maxw:         1180px;   /* content container width */
  --gutter:       1.5rem;

  /* Derived. Never a new hue, only a mix of the tokens above. */
  --bronze-hover: color-mix(in srgb, var(--bronze-fill) 78%, black);
  --rule-bronze:  color-mix(in srgb, var(--bronze) 40%, transparent);
}

/* --------------------------------------------------------------------------
   1b. Framework overrides
   ResponsiveTopNavDropdown.css loads first, for its #nav block. It is a whole
   page framework though, so a few of its globals land on this site whether we
   want them or not. Each one is undone here rather than further down, so the
   rest of the file reads as if the framework were not there.
   -------------------------------------------------------------------------- */
/* The framework sets html{font-size:18px}. Every size in this file is in rem,
   so leaving it would scale the entire site by 18/16 and break the clamp()
   ceilings and the px breakpoints against each other. */
html {
  font-size: 100%;
}

/* .container is a framework class too, and its max-width and margin are already
   overridden below. Its background-color is not: a pale blue would show through
   every cream and navy band's inner column. */
.container {
  background-color: transparent;
}

/* .card and .cards are framework class names as well. Everything else about
   them is already restated in 4.9, but the framework's drop shadow and its
   hover transition are not, so they would arrive uninvited on the three info
   cards. The cards are flat periwinkle panels by design. */
.card,
.card:hover {
  box-shadow: none;
  transition: none;
}

/* The framework floats #nav. A floated child would take the nav out of flow and
   collapse .site-header to zero height, and since <body> is a grid, <main> would
   then sit in its own row with the nav overlapping it. Making the header a grid
   container is the fix: floats do not apply to grid items, so this settles it
   without an !important war over the float itself. */
.site-header {
  display: grid;
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

/* Bands carry all vertical rhythm as padding, so element margins are zeroed
   and spacing is done with grid row-gap. Nothing can collapse. */
body,
h1, h2, h3,
p, ul, dl, dt, dd, figure {
  margin: 0;
  padding: 0;
}

/* Sticky footer. Every page is header / main / footer, so main takes the free
   row and pushes the footer to the bottom of the viewport on short pages,
   while long pages simply scroll as before. Not position:fixed: this footer is
   too tall to sit over the content on a phone.

   dvh follows vh so browsers without it keep the vh value. dvh is what makes
   this hold on mobile, where vh alone measures the viewport as if the address
   bar were hidden and leaves the footer just off-screen.

   minmax(0, 1fr) on the column stops a wide child from stretching the implicit
   auto column past the viewport and reintroducing the horizontal scroll the
   bleed sections are careful to avoid. */
body {
  display: grid;
  grid-template-rows: auto 1fr auto;
  grid-template-columns: minmax(0, 1fr);
  min-height: 100vh;
  min-height: 100dvh;
  background-color: var(--cream);
  color: var(--navy-ink);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  font-weight: 400;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.15;
}

img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

a {
  color: inherit;
}

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

/* Sections whose photo bleeds to one viewport edge: the copy side keeps the
   container inset, the photo side runs to the edge. Uses % not vw so a
   scrollbar cannot cause horizontal overflow. */
.bleed-right,
.bleed-left {
  --edge-pad: max(var(--gutter), calc((100% - var(--maxw)) / 2));
}

.bleed-right { padding-inline: var(--edge-pad) 0; }
.bleed-left  { padding-inline: 0 var(--edge-pad); }

.u-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Faked small caps: true small caps where the face offers them, uppercase
   plus wide tracking plus an enlarged initial everywhere else. Used only by
   "More Information" and the three card titles, per the reference. */
.u-smallcaps {
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-variant-caps: small-caps;
}

.u-smallcaps::first-letter {
  font-size: 1.18em;
}

/* --------------------------------------------------------------------------
   3. Bands
   -------------------------------------------------------------------------- */
.band {
  padding-block: var(--section-y);
}

.band--navy {
  background-color: var(--navy-deep);
  color: var(--white-soft);
}

.band--cream {
  background-color: var(--cream);
  color: var(--navy-ink);
}

.section-title {
  font-size: clamp(2.25rem, 5vw, 3.25rem);
  letter-spacing: 0.01em;
  color: var(--bronze);
}

.band--navy .section-title {
  color: var(--white-soft);
}

/* Body columns cap at roughly 62 characters. */
.about__copy p,
.rental__copy p,
.rental-row__copy p,
.card p,
.page-body p {
  max-width: 36rem;
}

/* --------------------------------------------------------------------------
   4.1 Top bar
   -------------------------------------------------------------------------- */
.topbar {
  display: grid;
  align-content: center;
  min-height: 44px;
  padding-block: 0.5rem;
  background-color: var(--cream);
  border-bottom: 2px solid var(--navy-deep);
}

.topbar__name {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  line-height: 1.15;
  text-transform: uppercase;
  text-align: center;
  color: var(--navy-deep);
}

/* --------------------------------------------------------------------------
   4.2 Nav
   Behaviour is the framework's: ResponsiveTopNavDropdown.css owns the collapse
   at 820px, the :target open/close and the absolute-positioned panel. This
   section only re-skins it to the club's cream / navy / Playfair.

   Specificity note, because it drives every selector below. The framework
   styles the nav through its id — #nav, #nav > ul, #nav li a — so a plain class
   selector loses to it. Anything that has to win is written with #nav in front.
   The one property that must NOT be written that way is display on .nav__list:
   the framework's own #nav > ul{display:none} and #nav:target > ul{display:block}
   are what open and close the menu, so display stays at plain class specificity
   and deliberately loses to them below 820px.
   -------------------------------------------------------------------------- */
#nav.nav {
  background-color: var(--cream);
  border-bottom: 3px solid var(--navy-deep);
  font-size: inherit;             /* framework sets 20px on #nav */
}

.nav__list {
  display: grid;                  /* see the specificity note above */
  grid-template-columns: repeat(6, auto);
  justify-content: center;
  column-gap: 2.75rem;
  padding-block: 0.8rem;
  list-style: none;
}

/* The framework spaces the desktop row with per-item margins (0 15px) and
   padding. The grid's column-gap already does that, and on mobile the tap
   target is better built out of padding on the link, so both are zeroed and
   the spacing is handled on .nav__link instead. */
#nav .nav__list > li {
  margin: 0;
  padding: 0;
}

#nav .nav__link {
  display: block;
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  line-height: 1.6;
  color: var(--navy-deep);        /* framework's #nav li a is #1e599b bold */
  text-decoration: none;
  transition: color 160ms ease;
}

#nav .nav__link:hover,
#nav .nav__link:focus-visible {
  color: var(--bronze-ink);
}

#nav .nav__link:focus-visible {
  outline: 2px solid var(--bronze-ink);
  outline-offset: 2px;
}

#nav .nav__link[aria-current="page"] {
  font-weight: 700;
}

/* The Menu / Close pair. The framework hides both above 820px and shows exactly
   one below it, so this rule sets no display of its own — adding one here would
   put both toggles on screen at desktop width. Matching the framework's
   "#nav:not(:target) > a:first-of-type" specificity exactly and winning on
   source order is why it is written #nav.nav > a.nav__toggle. */
#nav.nav > a.nav__toggle {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy-deep);
  padding-block: 0.85rem;
}

#nav.nav > a.nav__toggle:focus-visible {
  outline: 2px solid var(--bronze-ink);
  outline-offset: -4px;
}

/* --------------------------------------------------------------------------
   4.3 Hero banner
   -------------------------------------------------------------------------- */
.hero {
  padding-block: 0;
}

.hero__banner {
  display: grid;
}

/* Sizing lives on the image, not the wrapper. An aspect-ratio on the wrapper
   plus a min-height makes Chrome re-derive the *width* from the clamped
   height, which blows the box wider than the viewport and drags the logo
   off-centre. width:100% + height:auto keeps the natural ratio with no crop;
   min-height only engages below ~1150px, where object-fit then trims the
   artwork's wide empty margins instead of the logo. */
.hero__banner-img {
  grid-area: 1 / 1;
  width: 100%;
  height: auto;
  min-height: 360px;
  object-fit: cover;
  object-position: center;
}

/* Percentage margin resolves against width, so the offset tracks the artwork
   as it scales. The rem floor takes over once the image stops growing. */
.hero__cta {
  grid-area: 1 / 1;
  align-self: end;
  justify-self: center;
  margin-bottom: max(1.5rem, 3%);
}

/* --------------------------------------------------------------------------
   4.4 About Us
   -------------------------------------------------------------------------- */
/* Same treatment as the rentals: the scene bleeds the full height of the
   band, so the copy cell carries the vertical rhythm. */
.about {
  padding-block: 0;
}

/* The columns were always 1fr 1fr. What threw the split off was .bleed-right
   on the section, which inset the whole grid by --edge-pad on the left while
   leaving it flush right, so the midpoint of the grid sat right of the
   midpoint of the page and the image began around 59% across. The section no
   longer carries .bleed-right, so this grid spans the full viewport and 1fr
   1fr is a true half: the image's left edge lands on the exact horizontal
   centre. The page inset moved to .about__copy below. */
.about__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
}

.about__copy {
  display: grid;
  align-content: center;
  row-gap: 1.1rem;
  padding-block: var(--section-y);
  /* Half the inset .bleed-right used to apply, so the copy starts nearer the
     left edge. This column is exactly half the viewport, and the percentage
     resolves against it, so 50% - --maxw/4 works out to (viewport - maxw) / 4.
     % rather than vw, so a scrollbar cannot push it out. Floored at --gutter
     on narrow screens. The heading and the three paragraphs are all items in
     this one column, so they share this single left edge. */
  padding-inline: max(var(--gutter), calc(50% - var(--maxw) / 4)) 2.5rem;
}

/* Sunset scene fills the right half; the row of prints stacks into the same
   cell and pulls left so the first one breaks over onto the cream. */
/* The scene fills the box by absolute inset rather than height:100%. A
   percentage height cannot resolve against a box that is sized by stretch or
   by an auto grid row, and the image silently falls back to its intrinsic
   aspect and overflows. The prints stay in flow so the grid can centre them,
   and take position:relative to paint above the absolutely-placed scene. */
.about__media {
  position: relative;
  display: grid;
  align-content: center;
  min-height: 22rem;
}

/* Favour the golden horizon band rather than the dark cloud tops. */
.about__scene {
  position: absolute;
  inset: 0;
  object-position: center 42%;
}

.about__prints {
  position: relative;
  display: grid;
  grid-template-columns: 0.78fr 1.18fr 1fr;
  column-gap: 0.6rem;
  margin-inline: -3.5rem 1.5rem;
}

.about__prints img {
  height: clamp(8rem, 13vw, 11.5rem);
  border: 5px solid var(--white-soft);
}

/* --------------------------------------------------------------------------
   4.5 Location band
   -------------------------------------------------------------------------- */
.strip {
  padding-block: 1.75rem;
  background-color: var(--periwinkle);
}

/* A single banner line rather than a reading column, so it is capped wider
   than the 34rem body measure on purpose. */
.strip__line {
  max-width: 52rem;
  margin-inline: auto;
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1.5;
  text-align: center;
  color: var(--navy-deep);
}

/* --------------------------------------------------------------------------
   4.6 / 4.7 Rentals
   Two arrangements sharing one component. The diagonals are parallel: the
   kayak photo is wider at the top, the banquet photo wider at the bottom.
   -------------------------------------------------------------------------- */
/* No padding on the band itself: the photo bleeds the full height of the
   section, so the vertical rhythm is carried by the copy and price cells
   instead. */
.rental {
  padding-block: 0;
  background-color: var(--cream);
}

.rental__grid {
  display: grid;
  align-items: stretch;
}

.rental__copy,
.rental__price {
  padding-block: var(--section-y);
}

/* Two columns, not the old 40% / 24% / 36%. The middle column existed to hold
   the price figure; with the home page down to a heading and a button, a third
   column only pushed the button away from the heading it belongs to. Mirrors
   the banquet split below so the two bands read as a matched pair. */
.rental--kayak .rental__grid {
  grid-template-columns: 58% 42%;
}

.rental--banquet .rental__grid {
  grid-template-columns: 42% 58%;
}

.rental__copy {
  display: grid;
  align-content: center;
  row-gap: 1.1rem;
}

/* justify-items matters now that the button lives in this cell. Grid items are
   blockified, so the button's inline-grid becomes grid and the default stretch
   would run it the full width of the column. start sizes it to its label and
   pins it under the heading; the banquet cell does the same with end. */
.rental--kayak .rental__copy {
  justify-items: start;
  padding-inline-end: 2rem;
}

/* Banquet copy is right-aligned against the page edge inset. */
.rental--banquet .rental__copy {
  justify-items: end;
  padding-inline-start: 3rem;
  text-align: right;
}

/* See .about__media for why the photo fills by inset rather than height:100%. */
.rental__media {
  position: relative;
  align-self: stretch;
  overflow: hidden;
  min-height: 20rem;
}

.rental__media img {
  position: absolute;
  inset: 0;
}

.rental--kayak .rental__media {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 12% 100%);
}

.rental--banquet .rental__media {
  clip-path: polygon(0 0, 88% 0, 100% 100%, 0 100%);
}

/* Price sits on the band, not over the photo, so it needs no scrim. */
.rental__price {
  display: grid;
  justify-items: center;
  align-content: center;
  row-gap: 0.15rem;
  text-align: center;
}

.price {
  font-family: var(--font-display);
  font-size: clamp(2.8rem, 6vw, 4.2rem);
  font-weight: 700;
  line-height: 1.1;
  color: var(--bronze);
}

.price__unit {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 400;
  line-height: 1.15;
  color: var(--bronze-ink);
}

.rental__price .btn {
  margin-top: 1.1rem;
}

/* --------------------------------------------------------------------------
   4.7b Rentals, plain two-column rows
   Used on the Rentals page. Unlike .rental above there is no bleed and no
   clip-path: copy on one side, a rectangular photo on the other, and the
   price and button sit inside the copy column rather than in a third cell.
   Row order comes from source order, so the banquet row puts its photo first.
   -------------------------------------------------------------------------- */
.rental-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 3rem;
  width: 100%;
}

.rental-row + .rental-row {
  margin-top: var(--section-y);
}

.rental-row__copy {
  display: grid;
  align-content: center;
  justify-items: start;
  row-gap: 1.1rem;
}

.rental-row__media img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.rental-row__price {
  display: grid;
  justify-items: start;
  row-gap: 0.1rem;
}

/* Smaller than the home page figure, which stands alone in its own cell.
   Here it sits under a paragraph and would otherwise shout over it. */
.rental-row__price .price {
  font-size: clamp(2.4rem, 5vw, 3.2rem);
}

/* --------------------------------------------------------------------------
   4.8 Join Us
   -------------------------------------------------------------------------- */
.join__inner {
  display: grid;
  justify-items: center;
  row-gap: 0.5rem;
  text-align: center;
}

.join__subhead {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--white-soft);
}

.join__photos {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
  width: 100%;
  max-width: 720px;
  margin-block: 1.5rem;
}

.join__photos img {
  aspect-ratio: 4 / 3;
  height: auto;
}

/* A thin cream rule between two navy bands. On the home page it sits between
   Join Us and the footer, which are the same navy and would otherwise read as
   one unbroken block. Full bleed, no container. */
.band-rule {
  height: 10px;
  background-color: var(--cream);
}

/* --------------------------------------------------------------------------
   4.9 More Information
   -------------------------------------------------------------------------- */
.more__inner {
  display: grid;
  justify-items: center;
  row-gap: 2.25rem;
}

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.75rem;
  align-items: stretch;
  width: 100%;
}

/* auto / 1fr / auto pins the button to the bottom of every card. */
.card {
  display: grid;
  grid-template-rows: auto 1fr auto;
  justify-items: center;
  row-gap: 1rem;
  padding: 1.75rem;
  background-color: var(--periwinkle);
  text-align: center;
}

.card__title {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--navy-deep);
}

.card p {
  color: var(--navy-ink);
}

/* --------------------------------------------------------------------------
   4.10 Footer
   -------------------------------------------------------------------------- */
.site-footer {
  padding-block: 2.25rem 1.5rem;
  background-color: var(--navy-deep);
  color: var(--white-soft);
}

.footer__grid {
  display: grid;
  grid-template-columns: auto 1fr 1fr 1.15fr;
  align-items: start;
  gap: 2.5rem;
}

.footer__mark img {
  width: 76px;
  height: auto;
  object-fit: contain;
}

.footer__col {
  display: grid;
  align-content: start;
  row-gap: 0.15rem;
  font-size: 1rem;
}

.footer__heading {
  margin-bottom: 0.4rem;
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--white-soft);
}

.footer__link {
  text-decoration: none;
}

.footer__link:hover {
  text-decoration: underline;
}

.footer__link:focus-visible {
  outline: 2px solid var(--white-soft);
  outline-offset: 2px;
}

.footer__hours {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  column-gap: 1.75rem;
  row-gap: 0.15rem;
  font-size: 1rem;
  font-weight: 700;
}

.footer__colophon {
  margin-top: 1.5rem;
  font-size: 0.875rem;
  letter-spacing: 0.02em;
}

/* --------------------------------------------------------------------------
   4.11 Interior page header and body
   -------------------------------------------------------------------------- */
/* Interior pages carry a short version of the home banner. banner-small.jpg is
   derived from banner1-wide.jpg: the same logo block redrawn at 8:1 on the
   artwork's own texture, so the strip renders about 175px tall at desktop
   instead of the home hero's 437px.

   The strip is shown whole at every viewport width: width:100% + height:auto
   and nothing else. The earlier min-height/max-height pair was what cropped
   it — max-height:190px cut the bottom off the artwork on any viewport wider
   than ~1520px (a 1920px window renders the 8:1 strip 240px tall), and
   min-height:110px cropped the sides below ~880px. object-fit is gone with
   them: with no height clamp the box always matches the artwork's own ratio,
   so there is nothing left to fit. An aspect-ratio must stay off here — it
   would make Chrome re-derive the width from the height and overflow the
   viewport. */
.page-banner {
  padding-block: 0;
  background-color: var(--navy-deep);
}

.page-banner__img {
  display: block;
  width: 100%;
  height: auto;
}

.page-head {
  padding-block: 2.75rem;
  background-color: var(--navy-deep);
  color: var(--white-soft);
  text-align: center;
}

.page-head h1 {
  font-size: clamp(2.25rem, 5vw, 3.25rem);
  color: var(--white-soft);
}

/* A navy band butted straight onto the navy page head reads as one block, so
   the seam would otherwise carry both paddings at once. The head's own bottom
   padding is enough separation. */
.page-head + .band--navy {
  padding-block-start: 0;
}

.page-body__inner {
  display: grid;
  row-gap: 1.1rem;
  justify-items: start;
}

.page-body__inner .btn {
  margin-top: 0.75rem;
}

/* Centred variant. The 36rem measure on the paragraphs still applies, so the
   grid centres that column rather than letting the text run the full width. */
.page-body__inner--center {
  justify-items: center;
  text-align: center;
}

/* The block centres, but the term/value pairs stay left-aligned against each
   other. Centring the cells themselves leaves both columns ragged. */
.page-body__inner--center .detail-list {
  justify-content: center;
  text-align: left;
}

/* A single emphasised line pulled out of the body copy. --bronze-ink rather
   than --bronze: this can render below 24px at narrow widths, where --bronze
   would drop under the 4.5:1 floor. */
.lead {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.6vw, 1.75rem);
  font-weight: 700;
  line-height: 1.4;
  color: var(--bronze-ink);
}

.detail-list {
  display: grid;
  grid-template-columns: auto auto;
  justify-content: start;
  column-gap: 2rem;
  row-gap: 0.35rem;
  margin: 0;
}

.detail-list dt {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--bronze-ink);
}

/* Links sitting on a light band. The Contact page previously borrowed
   .footer__link, whose focus ring is --white-soft: invisible on --cream, so
   keyboard focus was effectively unmarked. --navy-ink on --cream is 9.7:1. */
.link {
  color: var(--navy-ink);
  text-decoration: underline;
  text-decoration-color: var(--rule-bronze);
  text-underline-offset: 0.15em;
  transition: color 160ms ease, text-decoration-color 160ms ease;
}

.link:hover {
  color: var(--bronze-ink);
  text-decoration-color: currentColor;
}

.link:focus-visible {
  outline: 2px solid var(--bronze-ink);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   4.11b Labelled detail groups
   A heading plus a two-column term/value list. Replaces the single long
   .detail-list on the Contact page, where one run of six pairs gave the hours
   no heading of their own and let the two-line address disturb the rows below.
   -------------------------------------------------------------------------- */
.info-group__title {
  margin-bottom: 0.6rem;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  /* --bronze-ink (4.68:1 on --cream), not --bronze (3.83:1). --bronze clears
     only the 3:1 large-text floor, and at 1.15rem this is normal text. */
  color: var(--bronze-ink);
}

/* max-content sizes the label column to the longest label in the group, so
   every value starts on the same x. Baseline alignment ties each label to the
   first line of its value: the address can wrap to two lines and the rows
   under it keep their rhythm. */
.info-list {
  display: grid;
  grid-template-columns: max-content 1fr;
  align-items: baseline;
  column-gap: 1.5rem;
  row-gap: 0.5rem;
  margin: 0;
}

.info-list dt {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--bronze-ink);
}

/* --------------------------------------------------------------------------
   4.12 Photo gallery
   Wider than .join__photos, which caps at 720px for a three-up row.
   -------------------------------------------------------------------------- */
.gallery {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
  width: 100%;
}

.gallery img {
  aspect-ratio: 4 / 3;
  height: auto;
}

/* Inside the .join band the row-gap is only 0.5rem, tuned for a heading sitting
   on its subhead. The gallery needs the same breathing room .join__photos has. */
.join__inner .gallery {
  margin-block: 1.5rem;
}

/* --------------------------------------------------------------------------
   4.13 Contact: details beside the map
   -------------------------------------------------------------------------- */
/* stretch, not start: the map cell takes the full height of the row so its top
   and bottom edges land on the top of the heading and the bottom of the
   buttons. The row is sized by the details column, which is the taller of the
   two once the map has no intrinsic height of its own. */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  gap: 2.5rem;
  width: 100%;
  text-align: left;
}

/* The two labelled groups and the buttons stack in the left cell. */
.contact-details {
  display: grid;
  align-content: start;
  row-gap: 2rem;
}

/* auto-fit rather than a fixed column flow: two buttons side by side need about
   26rem, which the left column does not have between the 768px stack and roughly
   1000px, and they used to overflow it. Below that the tracks collapse to one
   and the buttons stack on their own. min() keeps the track floor from ever
   exceeding the container on a narrow phone. Grid, not flexbox. */
.contact-actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), max-content));
  justify-content: start;
  gap: 1rem;
}

/* The 0.75rem from .page-body__inner .btn would push these off the row-gap. */
.contact-actions .btn {
  margin-top: 0;
}

/* Height comes from the row rather than an aspect-ratio, so the map matches the
   details column exactly instead of landing wherever 4:3 happens to end. The
   min-height both stops it collapsing if the copy is ever short and gives the
   row something to measure, since a percentage height contributes nothing to
   intrinsic sizing.

   overflow:hidden is what makes the radius actually clip the iframe, which
   paints its own opaque background over a rounded parent otherwise. */
.map-embed {
  width: 100%;
  height: 100%;
  min-height: 20rem;
  border-radius: 6px;
  overflow: hidden;
}

.map-embed iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* --------------------------------------------------------------------------
   4.14 Memberships: copy beside a column of community photos
   -------------------------------------------------------------------------- */
.membership-grid {
  display: grid;
  grid-template-columns: 1fr 0.8fr;
  align-items: stretch;
  gap: 3rem;
  width: 100%;
}

/* The copy sits in a raised panel rather than running loose on the band, so it
   reads as one block against the photo column. --white-soft over --cream is a
   light-on-light lift, which leaves every text token at the contrast it was
   chosen for; a --periwinkle panel would drop the bronze section title under
   the 3:1 floor and the bronze lead under 4.5:1. */
.membership-panel {
  padding: 2.5rem;
  background-color: var(--white-soft);
  border: 1px solid var(--rule-bronze);
}

/* Two equal rows stretched to the height of the panel, so the stack finishes
   level with it instead of running past. The photos inherit width/height 100%
   and object-fit:cover from the base img rule, so each one crops to its row.
   min-height stops them collapsing to slivers when the copy is short. */
.membership-photos {
  display: grid;
  grid-template-rows: repeat(2, 1fr);
  row-gap: 1.25rem;
  min-height: 32rem;
}

/* --------------------------------------------------------------------------
   5.1 Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-grid;
  place-items: center;
  padding: 0.75rem 1.75rem;
  border: 1px solid transparent;
  border-radius: 6px;
  font-family: var(--font-display);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.4;
  text-align: center;
  text-decoration: none;
  transition: background-color 160ms ease, color 160ms ease;
}

.btn--bronze {
  background-color: var(--bronze-fill);
  color: var(--white-soft);
}

.btn--bronze:hover {
  background-color: var(--bronze-hover);
}

.btn--bronze:focus-visible {
  outline: 2px solid var(--navy-deep);
  outline-offset: 2px;
}

/* Secondary button for light bands. .btn--cream and .btn--outline both carry a
   --white-soft focus ring, which disappears against --cream, so neither can be
   the secondary here. --bronze-ink on --cream is 4.68:1. */
.btn--bronze-outline {
  background-color: transparent;
  border-color: var(--bronze-fill);
  color: var(--bronze-ink);
}

.btn--bronze-outline:hover {
  background-color: var(--bronze-fill);
  color: var(--white-soft);
}

.btn--bronze-outline:focus-visible {
  outline: 2px solid var(--navy-deep);
  outline-offset: 2px;
}

.btn--cream {
  background-color: var(--white-soft);
  color: var(--navy-deep);
}

.btn--cream:hover {
  background-color: var(--cream);
}

.btn--cream:focus-visible {
  outline: 2px solid var(--white-soft);
  outline-offset: 2px;
}

.btn--outline {
  background-color: transparent;
  border-color: var(--white-soft);
  color: var(--white-soft);
}

.btn--outline:hover {
  background-color: var(--white-soft);
  color: var(--navy-deep);
}

.btn--outline:focus-visible {
  outline: 2px solid var(--periwinkle);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   6. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1024px) {
  :root {
    --section-y: 4rem;
  }

  .nav__list {
    column-gap: 1.5rem;
  }

  .about__prints {
    margin-inline: -2rem 1rem;
  }
}

/* 820px is the framework's nav breakpoint as well as this file's, so the
   dropdown appears on the same step everything else stacks on. */
@media (max-width: 820px) {
  /* The framework's open panel is #ccc and sits 8px below the bar, which would
     show a strip of the page through the seam. Cream, flush, and carrying the
     same navy rule as the bar, so open or closed it reads as one block. The
     !important is not a preference: the framework's margin-top carries one. */
  #nav > .nav__list {
    margin-top: 0 !important;
    padding-block: 0.35rem 0.9rem;
    background-color: var(--cream);
    border-bottom: 3px solid var(--navy-deep);
  }

  /* Padding rather than margin, so the full width of the row is tappable. With
     the 1.6 line-height this clears the 44px minimum target. */
  #nav .nav__link {
    padding-block: 0.6rem;
    font-size: 1.15rem;
  }

  .bleed-right,
  .bleed-left {
    padding-inline: 0;
  }

  .about__grid {
    grid-template-columns: 1fr;
    row-gap: 2rem;
  }

  .about__copy {
    padding-block: var(--section-y) 0;
    padding-inline: var(--gutter);
  }

  .about__grid {
    padding-bottom: var(--section-y);
  }

  .about__media {
    min-height: 0;
  }

  .about__scene {
    height: 16rem;
  }

  .about__prints {
    margin-inline: var(--gutter);
  }

  /* Photo becomes a plain full-width block, no clip-path. */
  /* Was padding-bottom only, which worked while the photo led the stack and
     could sit flush against the section above it. The copy leads now, so the
     band needs its top padding back or the heading butts straight onto the
     location strip. Both edges, which is the same rhythm .band carries. */
  .rental__grid,
  .rental--kayak .rental__grid,
  .rental--banquet .rental__grid {
    grid-template-columns: 1fr;
    row-gap: 1.75rem;
    padding-block: var(--section-y);
  }

  /* Stacked order for both rental sections, and the reason it is `order` rather
     than `grid-row`: copy, then the price block, then the photo. The reader gets
     the heading and the terms first, the figure and its button next, and the
     scene last, instead of scrolling past a photo to reach a bare "$30".

     grid-row would pin the photo to row 3 in the banquet section too, where
     there is no .rental__price to fill row 2 — an empty row still costs a
     row-gap, so the copy and photo would drift apart. `order` feeds the same
     sequence into auto-placement, which only creates the rows it fills.

     Source order already reads copy-then-photo for the kayak section and the
     reverse for the banquet one; this normalizes both without touching either
     page's markup, and the DOM order that assistive tech follows is unchanged.  */
  .rental__copy,
  .rental--kayak .rental__copy,
  .rental--banquet .rental__copy {
    order: 1;
    justify-items: center;
    padding-inline: var(--gutter);
    text-align: center;
  }

  .rental__price {
    order: 2;
  }

  .rental__media {
    order: 3;
    min-height: 0;
    height: 260px;
    clip-path: none;
  }

  /* The band regains its own rhythm once the photo is a stacked block. */
  .rental__copy,
  .rental__price {
    padding-block: 0;
  }

  .rental--kayak .rental__media,
  .rental--banquet .rental__media {
    clip-path: none;
  }

  /* Photo above copy in both rows, so the banquet row keeps its source order
     and the kayak row is reversed into it. */
  .rental-row {
    grid-template-columns: 1fr;
    gap: 1.75rem;
  }

  .rental-row--kayak .rental-row__media {
    grid-row: 1;
  }

  .gallery {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Stacked under the copy, the photos go back to their own 4:3 rather than
     stretching to a height there is no longer a copy column to match. */
  .membership-grid {
    grid-template-columns: 1fr;
  }

  .membership-panel {
    padding: 1.75rem;
  }

  .membership-photos {
    grid-template-rows: none;
    min-height: 0;
  }

  .membership-photos img {
    aspect-ratio: 4 / 3;
    height: auto;
  }
}

/* Contact only. The rest of the file breaks at 1024 / 820 / 600; the details
   and map need to part company slightly later than the 820 stack does. */
@media (max-width: 768px) {
  /* Source order is details then map, so text lands first with no reordering. */
  .contact-grid {
    grid-template-columns: 1fr;
  }

  /* Stacked, there is no column left to match, so the map takes a fixed height.
     min-height has to be cleared or the 20rem floor would beat the 300px. */
  .map-embed {
    height: 300px;
    min-height: 0;
  }
}

@media (max-width: 600px) {
  /* The nav used to wrap onto three columns here. Below 820px it is the
     framework's dropdown instead, one item per row, so there is nothing left
     to rewrap and the old .nav__list override is gone. */

  .about__prints {
    grid-template-columns: 1fr 1fr;
  }

  .about__prints img:last-child {
    grid-column: 1 / -1;
  }

  .cards,
  .join__photos,
  .gallery {
    grid-template-columns: 1fr;
  }

  .footer__grid {
    grid-template-columns: 1fr;
    justify-items: start;
    text-align: left;
    gap: 1.75rem;
  }

  .footer__mark {
    justify-self: center;
  }

  .detail-list {
    grid-template-columns: 1fr;
    row-gap: 0;
  }

  .detail-list dd {
    margin-bottom: 0.6rem;
  }

  /* "Saturday & Sunday" plus its value plus a 1.5rem gap is 269px, which does
     not clear a 320px viewport once the gutters are off. */
  .info-list {
    column-gap: 1rem;
  }

  /* 1.75rem of inline padding pushes "Call (309) 788-9412" to 286px, wider than
     a 320px viewport can hold. */
  .btn {
    padding-inline: 1.25rem;
  }
}

/* --------------------------------------------------------------------------
   7. Reduced motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}
