/* ==========================================================================
   Lana Filippova Interiors — hub cards and galleries
   Child theme. Companion to lfi-nav.css, kept separate because that file owns
   the header and this one owns page content.

   Both grids are deliberately OURS rather than the theme's
   `img-boxes isotope-container ... masonry`. Isotope absolutely positions its
   children from JavaScript and lays every photograph out at its own aspect
   ratio, which is what made the galleries a ragged wall of mismatched tiles
   that changed shape from page to page. A plain CSS grid with a fixed frame
   cannot do that, needs no JS, and cannot be broken by a plugin update.
   ========================================================================== */

:root {
  --lfi-c-accent: #65aeb4;
  --lfi-c-ink: #2f3437;
  --lfi-c-muted: #6c7378;
  --lfi-c-line: #e4e7e9;
  --lfi-c-ground: #f7f8f9;
  --lfi-c-gap: 26px;
  --lfi-c-radius: 2px;
}

/* ------------------------------------------------------------- hub cards -- */
.lfi-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: var(--lfi-c-gap);
  margin: 0 0 42px;
  padding: 0;
  list-style: none;
}

.lfi-card {
  display: flex;
  flex-direction: column;      /* so every card's CTA sits on the same baseline */
  background: #fff;
  border: 1px solid var(--lfi-c-line);
  border-radius: var(--lfi-c-radius);
  overflow: hidden;
  transition: box-shadow .18s ease, transform .18s ease, border-color .18s ease;
}
.lfi-card:hover {
  border-color: #cfd6d8;
  box-shadow: 0 10px 28px -18px rgba(0, 0, 0, .45);
  transform: translateY(-2px);
}
/* The whole card reads as one control even though only the text is clickable. */
.lfi-card:focus-within {
  border-color: var(--lfi-c-accent);
  box-shadow: 0 0 0 2px rgba(101, 174, 180, .35);
}

/* THE UNIFORM FRAME. A fixed ratio plus object-fit is what makes a portrait
   photograph and a landscape one occupy identical tiles. aspect-ratio is not
   in every browser we might meet, so the padding-top fallback stays. */
.lfi-card-media {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--lfi-c-ground);
  overflow: hidden;
}
@supports not (aspect-ratio: 4 / 3) {
  .lfi-card-media { height: 0; padding-top: 75%; }
}
.lfi-card-media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  transition: transform .4s ease;
}
.lfi-card:hover .lfi-card-media img { transform: scale(1.03); }

.lfi-card-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 20px 22px 22px;
}

.lfi-card-title {
  margin: 0 0 10px;
  font-size: 19px;
  line-height: 1.3;
}
.lfi-card-title a { color: var(--lfi-c-ink); text-decoration: none; }
.lfi-card-title a:hover,
.lfi-card-title a:focus-visible { color: var(--lfi-c-accent); }

.lfi-card-blurb {
  margin: 0 0 16px;
  color: var(--lfi-c-muted);
  font-size: 15px;
  line-height: 1.6;
}

.lfi-card-cta {
  margin: auto 0 0;            /* pinned to the bottom of an uneven card */
  font-size: 14px;
  line-height: 1.4;
}
.lfi-card-cta a {
  color: var(--lfi-c-accent);
  text-decoration: none;
  font-weight: 600;
  letter-spacing: .01em;
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
}
.lfi-card-cta a::after {
  content: "\2192";            /* the arrow is decoration on a link that already
                                  says where it goes, so it carries no text */
  transition: transform .18s ease;
}
.lfi-card-cta a:hover::after { transform: translateX(3px); }
.lfi-card-cta a:hover,
.lfi-card-cta a:focus-visible { text-decoration: underline; }

/* A card whose page has no photography yet keeps the same frame, as a quiet
   tinted panel with the studio's accent mark. It has to read as a decision
   rather than as an image that failed to load - and it has to occupy the same
   space, or a text-only card opens a hole beside a photographed neighbour. */
.lfi-card-media--empty {
  background:
    radial-gradient(circle at 50% 45%, rgba(101, 174, 180, .16) 0 42px, transparent 43px),
    linear-gradient(135deg, #eef1f2 0%, #e2e7e9 100%);
  border-bottom: 1px solid var(--lfi-c-line);
}
.lfi-card-media--empty::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 45%;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border: 2px solid rgba(101, 174, 180, .55);
  transform: rotate(45deg);
}

/* -------------------------------------------------------------- galleries - */
.lfi-gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
  margin: 0 0 42px;
}
.lfi-gallery-item {
  position: relative;
  margin: 0;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--lfi-c-ground);
  border-radius: var(--lfi-c-radius);
}
@supports not (aspect-ratio: 4 / 3) {
  .lfi-gallery-item { height: 0; padding-top: 75%; }
}
.lfi-gallery-item img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  transition: transform .5s ease;
}
.lfi-gallery-item:hover img { transform: scale(1.04); }

@media (max-width: 599px) {
  :root { --lfi-c-gap: 18px; }
  .lfi-cards { grid-template-columns: 1fr; }
  .lfi-gallery { grid-template-columns: repeat(2, 1fr); gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .lfi-card,
  .lfi-card-media img,
  .lfi-gallery-item img,
  .lfi-card-cta a::after { transition: none !important; }
  .lfi-card:hover { transform: none; }
  .lfi-card:hover .lfi-card-media img,
  .lfi-gallery-item:hover img { transform: none; }
}

/* ----------------------------------------------------------- the lightbox - */
/* Magnific Popup ships with the parent theme; this is only skinning, so that
   the viewer looks like the rest of the site rather than like a plugin. */
.lfi-gallery-link {
  display: block;
  width: 100%;
  height: 100%;
  cursor: zoom-in;
}
/* The affordance: without it nothing says a tile can be opened. */
.lfi-gallery-item::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(19, 24, 30, .28) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='34' height='34' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round'%3E%3Ccircle cx='10.5' cy='10.5' r='6.5'/%3E%3Cpath d='M15.5 15.5 21 21M10.5 7.5v6M7.5 10.5h6'/%3E%3C/svg%3E") center no-repeat;
  opacity: 0;
  transition: opacity .2s ease;
  pointer-events: none;
}
.lfi-gallery-item:hover::after,
.lfi-gallery-item:focus-within::after { opacity: 1; }

/* The backdrop carries its alpha in the COLOUR and holds opacity at 1.
   Magnific animates .mfp-bg's opacity through its own ready/removing classes,
   so an `opacity` here is fought over during and after the transition and the
   page shows through. Stacked above .preheader's 1080 as well: that panel is
   deliberately above the navbar, which also put the theme's contact tab on top
   of the viewer. */
.lfi-mfp.mfp-bg {
  background: rgba(9, 12, 15, .97) !important;
  opacity: 1 !important;
  z-index: 1090;
}
.lfi-mfp.mfp-wrap { z-index: 1091; }
.lfi-mfp .mfp-container { padding: 0 56px; }
.lfi-mfp .mfp-figure::after { box-shadow: none; background: transparent; }
.lfi-mfp img.mfp-img { padding: 42px 0 56px; }

.lfi-mfp .mfp-title {
  color: rgba(255, 255, 255, .88);
  font-size: 14px;
  line-height: 1.5;
  padding-right: 60px;
  text-align: left;
}
.lfi-mfp .mfp-counter {
  color: rgba(255, 255, 255, .55);
  font-size: 13px;
  letter-spacing: .04em;
}

/* The plugin's default arrows are CSS TRIANGLES drawn with ::before (a dark
   backing) and ::after (the white arrowhead) on an otherwise empty <button>.
   There is no inner element to style - an earlier attempt targeted a span and
   left the arrows invisible. ::before goes; ::after becomes a chevron. */
.lfi-mfp .mfp-arrow {
  width: 56px;
  height: 56px;
  margin-top: -28px;
  opacity: .7;
  transition: opacity .15s ease, background .15s ease;
  border-radius: 50%;
}
.lfi-mfp .mfp-arrow:hover,
.lfi-mfp .mfp-arrow:focus { opacity: 1; background: rgba(255, 255, 255, .1); }
.lfi-mfp .mfp-arrow::before { display: none !important; }
.lfi-mfp .mfp-arrow::after {
  content: "" !important;
  display: block !important;
  position: absolute;
  left: 50%;
  top: 50%;
  width: 15px;
  height: 15px;
  margin: -8px 0 0 -8px;
  border: 0;
  border-left: 2px solid #fff;
  border-bottom: 2px solid #fff;
  opacity: 1;
}
.lfi-mfp .mfp-arrow-left::after  { transform: rotate(45deg);   margin-left: -4px; }
.lfi-mfp .mfp-arrow-right::after { transform: rotate(-135deg); margin-left: -12px; }

.lfi-mfp .mfp-close {
  color: #fff;
  opacity: .75;
  font-size: 32px;
  width: 52px;
  height: 52px;
}
.lfi-mfp .mfp-close:hover { opacity: 1; }
.lfi-mfp button:focus-visible { outline: 2px solid var(--lfi-c-accent); outline-offset: -4px; }

@media (max-width: 599px) {
  .lfi-mfp .mfp-container { padding: 0 8px; }
  .lfi-mfp .mfp-arrow { width: 48px; height: 48px; margin-top: -24px; }
  /* On a phone the arrows would sit on top of the photograph, so they move to
     the bottom corners where the counter and caption already are. */
  .lfi-mfp .mfp-arrow-left { left: 4px; }
  .lfi-mfp .mfp-arrow-right { right: 4px; }
  .lfi-mfp .mfp-title { padding-right: 0; font-size: 13px; }
  /* Touch: the tap target IS the image half, so the hover overlay would stick. */
  .lfi-gallery-item::after { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .lfi-gallery-item::after,
  .lfi-mfp .mfp-arrow { transition: none !important; }
}

/* ------------------------------------------------- homepage: welcome ------ */
/* The section is the client's own page-builder block; nothing here edits her
   builder data. The class is added at render by a filter in functions.php,
   anchored on `.special-heading` rather than on the section's generated id.

   The builder gives us three equal columns in the order text | photo | text,
   which splits one continuous piece of writing around a portrait and leaves the
   reader jumping over it. Grid puts the portrait FIRST and the writing beside
   it, without touching her markup - the source order is unchanged, only the
   visual order. */
.lfi-welcome {
  background:
    linear-gradient(180deg, #ffffff 0%, var(--lfi-c-ground) 22%, var(--lfi-c-ground) 100%);
  padding-top: 84px !important;
  padding-bottom: 84px !important;
  border-bottom: 1px solid var(--lfi-c-line);
}

/* Heading row: left-aligned, with the rule under it rather than centred, so it
   sits over the column of writing instead of floating above the whole band.

   This block carries the page's H1 (the slider carries none - see
   functions.php), so the heading is sized as the main heading of the page and the
   greeting above it is set small. The wide letter-spacing that suited a short
   "WELCOME TO ..." line is wrong on a sentence, so it moves to the greeting. */
.lfi-welcome .heading-block { margin-bottom: 46px; text-align: left !important; }
.lfi-welcome-eyebrow {
  font-size: 12px;
  letter-spacing: .2em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--lfi-c-accent-text);
  margin: 0 0 14px;
}
.lfi-welcome .special-heading {
  font-size: clamp(26px, 3.2vw, 40px);
  letter-spacing: .01em;
  font-weight: 600;
  line-height: 1.22;
  color: var(--lfi-c-ink);
  margin: 0;
  max-width: 22ch;
  text-wrap: balance;
}
.lfi-welcome .heading-block-line::after,
.lfi-welcome .heading-block-line::before { margin-left: 0 !important; }

/* The three builder columns, re-laid. */
@media (min-width: 992px) {
  .lfi-welcome .row + .row {
    display: grid;
    grid-template-columns: 330px 1fr 1fr;
    gap: 46px;
    align-items: start;
    margin: 0;
  }
  /* Bootstrap clears .row with ::before and ::after. Inside a GRID container
     those generated boxes become grid ITEMS and silently occupy two cells,
     which pushed the first text column into column three and wrapped the second
     onto a new row. They have no job here: nothing is floated any more. */
  .lfi-welcome .row + .row::before,
  .lfi-welcome .row + .row::after { content: none !important; display: none !important; }
  .lfi-welcome .row + .row > [class*="col-"] {
    width: auto !important;
    float: none !important;
    padding: 0 !important;
  }
  /* the portrait column is the second child in the source; show it first */
  .lfi-welcome .row + .row > [class*="col-"]:nth-child(2) { order: -1; }
}

/* The portrait, given a frame it did not have: an accent block offset behind
   the photograph. The original file is 259x451, so it is never stretched past
   its own width. */
.lfi-welcome .row + .row > [class*="col-"]:nth-child(2) { position: relative; }
/* Offset down and to the right of the photograph, so the frame reads as a
   frame. Sized to the file's own 259x451, which is what it renders at inside a
   330px column - it is never upscaled. Desktop only: below that the photograph
   centres and an offset rule would just look like a mistake. */
@media (min-width: 992px) {
  .lfi-welcome .row + .row > [class*="col-"]:nth-child(2)::before {
    content: "";
    position: absolute;
    left: 20px;
    top: 20px;
    width: 259px;
    height: 451px;
    border: 1px solid var(--lfi-c-accent);
    opacity: .55;
    pointer-events: none;
  }
}
.lfi-welcome img {
  position: relative;
  display: block;
  width: auto;
  max-width: 100%;
  height: auto;
  margin: 0;
  box-shadow: 0 26px 54px -30px rgba(0, 0, 0, .6);
}
@media (max-width: 991px) {
  .lfi-welcome img { margin: 0 auto; }
}

/* The copy was 14px at a tight leading across a 380px column, which is hard
   work for two long paragraphs. The first paragraph is lifted slightly so the
   band opens on something with a bit of weight. */
.lfi-welcome .text-block p {
  font-size: 15.5px;
  line-height: 1.8;
  color: #5c6368;
  margin: 0 0 18px;
}
.lfi-welcome .text-block p:last-child { margin-bottom: 0; }
.lfi-welcome .row + .row > [class*="col-"]:nth-child(1) .text-block p:first-child {
  font-size: 17px;
  line-height: 1.7;
  color: #454b4f;
}

/* The builder writes the button's colours as INLINE styles, so restyling it
   needs !important - there is nowhere else to win. */
.lfi-welcome .custom-button {
  display: inline-block;
  margin-top: 26px;
  padding: 14px 28px !important;
  font-size: 13px !important;
  letter-spacing: .09em;
  background-color: var(--lfi-c-accent) !important;
  border: 1px solid var(--lfi-c-accent) !important;
  color: #fff !important;
  border-radius: var(--lfi-c-radius) !important;
  transition: background-color .18s ease, border-color .18s ease, transform .18s ease;
}
.lfi-welcome .custom-button:hover,
.lfi-welcome .custom-button:focus-visible {
  background-color: #4e979d !important;
  border-color: #4e979d !important;
  color: #fff !important;
  transform: translateY(-1px);
}

/* ------------------------------------------------ homepage: services ------ */
.lfi-services {
  background: #fff;
  padding-top: 76px !important;
  padding-bottom: 76px !important;
}
.lfi-services .special-heading {
  font-size: clamp(21px, 2.2vw, 29px);
  letter-spacing: .14em;
  font-weight: 600;
  color: var(--lfi-c-ink);
  margin: 0;
}
.lfi-services .heading-block { margin-bottom: 20px; }
.lfi-services-intro {
  max-width: 680px;
  margin: 0 auto 36px;
  text-align: center;
}
.lfi-services-intro p {
  font-size: 16px;
  line-height: 1.7;
  color: var(--lfi-c-muted);
  margin: 0;
}
.lfi-services-more { margin-top: 6px; }
.lfi-services-more .btn {
  padding: 13px 26px;
  font-size: 13px;
  letter-spacing: .08em;
  border-radius: var(--lfi-c-radius);
}

@media (max-width: 767px) {
  .lfi-welcome,
  .lfi-services { padding-top: 52px !important; padding-bottom: 52px !important; }
  .lfi-welcome .heading-block { margin-bottom: 28px; }
  .lfi-welcome .col-sm-4 + .col-sm-4 { margin-top: 26px; }
  .lfi-welcome img { max-width: 260px; }
}

/* ------------------------------------------------- button hover contrast -- */
/* The theme fights itself here. Its generated colour CSS sets the hover
   background to charcoal (#191e28), while css/style.css keeps the hover TEXT at
   #333333. A hovered button is therefore #333 on #191e28: a contrast ratio of
   1.32:1, where WCAG AA asks for 4.5:1. The label effectively disappears under
   the cursor. White takes it to 16.7:1.

   Note for whoever reads this next: the RESTING state is white on the brand
   teal #65aeb4, which measures 2.54:1 and also fails AA. That is a brand colour
   decision rather than a bug, so it is left alone and reported. */
.btn-default:hover,
.btn-default:focus,
.btn-default:active,
.btn-default.active,
.open .dropdown-toggle.btn-default,
.form-wrapper.contact-form input[type="submit"]:hover,
.form-wrapper.contact-form input[type="submit"]:focus {
  color: #fff !important;
}

/* ------------------------------------------------------- colour contrast -- */
/* The brand teal #65aeb4 is fine as a decorative colour and fails as a text
   colour. Measured on the live page:
       #65aeb4 text on white ............ 2.54:1
       #65aeb4 text on the tinted ground  2.39:1
       white text on #65aeb4 ............ 2.54:1
   WCAG AA asks 4.5:1 for text this size. The theme sets `a { color: #65aeb4 }`,
   so that covered every link in every paragraph on the site, not just buttons.

   #3b767c is the same hue two steps darker: 5.16:1 as text on white, 4.73:1 on
   the #f5f5f5 title bar, and the same both ways as a button behind a white
   label. #3d7a80 was the first choice and measured 4.49:1 on the title bar,
   missing the 4.5 threshold by a hundredth. The brand teal is UNCHANGED everywhere it is decoration - heading
   rules, borders, focus rings, the empty-card mark - and unchanged on dark
   grounds, where it already measured 6.57:1 in the footer and needs no help. */
:root { --lfi-c-accent-text: #3b767c; }

/* Accent as text, on light grounds only. Specificity beats the theme's bare
   `a` rule whichever order the stylesheets happen to print in. */
.main-content a:not(.btn),
.glacier-section a:not(.btn),
.text-block a:not(.btn),
.lfi-services-intro a,
.lfi-card-cta a { color: var(--lfi-c-accent-text); }
.lfi-card-title a:hover,
.lfi-card-title a:focus-visible { color: var(--lfi-c-accent-text); }

/* Filled buttons: the darker teal behind the white label they already had. */
.btn-default,
.form-wrapper.contact-form input[type="submit"],
.lfi-hero-actions .lfi-cta-primary,
.lfi-welcome .custom-button {
  background-color: var(--lfi-c-accent-text) !important;
  border-color: var(--lfi-c-accent-text) !important;
  color: #fff !important;
}
.lfi-hero-actions .lfi-cta-primary:hover,
.lfi-hero-actions .lfi-cta-primary:focus-visible {
  background-color: #33686d !important;
  border-color: #33686d !important;
}

/* The base rule above is !important, so it was also beating the theme's own
   hover background and the button stopped changing under the cursor at all.
   The charcoal hover is restored explicitly: white on #191e28 is 16.7:1. */
.btn-default:hover,
.btn-default:focus,
.btn-default:active,
.btn-default.active,
.form-wrapper.contact-form input[type="submit"]:hover,
.form-wrapper.contact-form input[type="submit"]:focus {
  background-color: #191e28 !important;
  border-color: #191e28 !important;
  color: #fff !important;
}

/* Our own credit line in the footer measured 3.13:1 on the dark ground. The
   footer's other secondary text is #9a9a9a, which measures 5.93:1 there. */
.custom-footer a[href*="jw-digital"],
.custom-footer .copyright a { color: #9a9a9a; }

/* The broad rule above also caught the card headings, which are ink by design:
   the heading is the name and the link below it is the accent. Restored here,
   after it, because the two selectors have equal specificity. */
.lfi-card-title a { color: var(--lfi-c-ink); }

/* Two pieces of theme text that are not links and so were missed by a
   link-only sweep. Both measured on the page:
     breadcrumb current item  #65aeb4 on #f5f5f5 ..... 2.33:1
     footer copyright line    #666666 on #12171f ..... 3.13:1
   The footer's other secondary text is #9a9a9a there, at 5.93:1. */
.breadcrumb li.active,
.breadcrumbs li.active { color: var(--lfi-c-accent-text); }
.subfooter,
.subfooter p,
.subfooter a { color: #9a9a9a; }
