/* Redmon Technologies — static site
   Rebuilt from the 2018 WordPress/Elementor original. No JS, no external requests. */

/* ---------- fonts (self-hosted, latin subset) ---------- */
@font-face{font-family:Lato;font-style:normal;font-weight:400;font-display:block;
  src:url(fonts/lato-400.woff2) format('woff2')}
@font-face{font-family:Lato;font-style:normal;font-weight:700;font-display:block;
  src:url(fonts/lato-700.woff2) format('woff2')}
@font-face{font-family:Poppins;font-style:normal;font-weight:700;font-display:block;
  src:url(fonts/poppins-700.woff2) format('woff2')}
@font-face{font-family:Vidaloka;font-style:normal;font-weight:400;font-display:block;
  src:url(fonts/vidaloka-400.woff2) format('woff2')}
@font-face{font-family:Roboto;font-style:normal;font-weight:100 900;font-display:block;
  src:url(fonts/roboto-var.woff2) format('woff2')}
@font-face{font-family:Raleway;font-style:normal;font-weight:100 900;font-display:block;
  src:url(fonts/raleway-var.woff2) format('woff2')}
@font-face{font-family:fa;font-style:normal;font-weight:400;font-display:block;
  src:url(fonts/fa-subset.woff2) format('woff2')}

/* ---------- palette ----------
   Every colour the site uses, in one place. The editor (tools/editor.py) reads
   the `@palette` labels below to build its colour pickers, so keep the comment
   immediately above each variable.
   The five near-identical reds are inherited from the original, which set each
   Services heading separately. Point them all at --brand to unify. */
:root{
  /* @palette Page background */            --page-bg:#ffffff;
  /* @palette Body text */                  --body-text:#87898a;
  /* @palette Header background */          --header-bg:#3d3d3d;
  /* @palette Content band background */    --band-bg:#333333;
  /* @palette Text on dark bands */         --on-dark:#ffffff;
  /* @palette Strong text */                --text-strong:#000000;

  /* @palette Brand red */                  --brand:#f91800;
  /* @palette Brand red (variant 2) */      --brand-alt:#f71000;
  /* @palette Brand red (variant 3) */      --brand-alt2:#f91000;
  /* @palette Heading red */                --accent-red:#ff0000;
  /* @palette Icon red */                   --icon-red:#f70000;

  /* @palette Section divider */            --divider:#7a7a7a;
  /* @palette Mobile menu divider */        --menu-divider:#e4e4e4;

  /* @palette Contact photo overlay */      --contact-overlay:#02122d;
  /* @palette Contact heading */            --contact-heading:#bababa;
  /* @palette Contact card title */         --card-title:#777777;
  /* @palette Contact card text */          --card-text:#b5b5b5;
}

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--page-bg);color:var(--body-text);font:400 16px/26px Lato,sans-serif}
a{color:var(--body-text);text-decoration:none}
/* used only by 404.html, so the site can run a strict CSP with no inline styles */
.link-brand{color:var(--brand)}
/* Bootstrap 3.3.6 ships normalize's `a:active,a:hover{outline:0}` (bootstrap.min.css,
   offset 626, before its own focus rule at 16152) and the original inherits it.
   Nothing paints either way -- outline-style is `none` in both states -- but the
   declared width is not the same, and WebKit reports the specified outline-width
   through getComputedStyle even when the style is none. So on the original, hovering
   any link whose element carries a transition animates outline-width from the
   initial `medium` (3px) down to 0 over that transition's duration. Measured on
   a.elementor-icon on the contact page in WebKit: 3px -> 0px over 500ms, one
   getAnimations() entry. Without this rule the rebuild's equivalent anchor does
   nothing at all on hover, which behaviour_diff reports as motion-one-side-only
   plus outcome-differs. Chromium and Firefox report 0px in the resting state, so
   neither side moves there and the symptom is WebKit-only.
   Order matters: the focus rule below must come after this one, at equal
   specificity, so a focused link keeps its ring while hovered -- which is what the
   original does (5px auto, measured on both sides). */
a:active,a:hover{outline:0}
/* the original inherits Bootstrap's focus ring; Chrome's default is thinner */
a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}
img{border:0;vertical-align:middle;max-width:100%;height:auto}
h1,h2,h3{margin:0;font-weight:700}
ul{margin:0;padding:0;list-style:none}

.container{width:100%;padding:0 15px;margin:0 auto}
@media(min-width:768px){.container{width:750px}}
@media(min-width:992px){.container{width:970px}}
@media(min-width:1200px){.container{width:1170px}}
.clearfix::after{content:"";display:table;clear:both}

.icon{font-family:fa;font-style:normal;font-weight:400;line-height:1;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
.icon-phone::before{content:"\f095"}
.icon-envelope::before{content:"\f003"}
.icon-bars::before{content:"\f0c9"}

/* ---------- header ---------- */
/* The nav is a CSS-only disclosure: a visually-hidden checkbox drives the mobile panel,
   so the site needs no JavaScript. At 993px and up the panel is absolutely positioned
   into the top bar, which is where the original put it. */
.site-header{position:relative;background:var(--header-bg)}
.site-header--home{background:var(--page-bg) url(img/logo.png) no-repeat 50% 0;background-size:contain}
.nav-check{position:absolute;width:0;height:0;opacity:0;pointer-events:none}

.bar{padding:20px 0}
.bar .container{padding:0}
.brand{float:left;width:66.66666667%;padding:0 15px;min-height:1px}
/* This anchor is the logo link. It is empty and `height:0` on both sides -- the
   original's is `<a class="header-logo"> </a>`, whose single space collapses, so
   it generates no line box -- so nothing about it paints until it is focused and
   the browser draws a ring on its zero-height box. Three things have to match,
   and none of them can move a settled pixel.

   COLOUR. The ring is drawn in currentColor (Firefox keeps Bootstrap's
   `outline: thin dotted` because it drops the `-webkit-focus-ring-color` line
   that follows it). illdy main.css sets

       #header .top-header .header-logo { color: #fff; ... }

   at specificity (1,2,0), which outranks the Customizer's `a:focus{color:#7a7878}`,
   so the ring is white on the original -- measured white on all four pages,
   including the home page, whose header background is light.

   OFFSET. illdy also sets `#header .top-header .row { display:flex;
   align-items:center }`, so the original's 1px-tall logo column is centred
   against the taller nav column instead of sitting at the row's top. The rebuilt
   bar is a float row and has to stay one: 720 pixel cells depend on its
   sub-pixel accumulation. So the centring is reproduced on the anchor alone,
   which moves no layout, with

       offset = (row height - column height) / 2,  column height = min-height 1px

   The row height is the nav column's, and it is NOT one number:

       below 993px   the row is the 78px .nav-toggle   -> (78-1)/2 = 38.5px
       993px and up  the row is the 60px .nav-wrap     -> (60-1)/2 = 29.5px

   Measured on the original at 320/360/501/767/768/992/993/1024/1280/1441 on all
   four pages in all three engines: 38.5 up to and including 992, 29.5 from 993,
   and the row height matches (78/60) in every cell.

   TRANSITION. `all 0.3s`, straight off the same illdy rule. It is why focusing
   the original's logo fades the ring in over 300ms (two running animations,
   outline-width and outline-offset) where the rebuild's snapped. */
.brand a{display:block;height:0;position:relative;top:38.5px;
  color:var(--on-dark);transition:all .3s}
@media(min-width:993px){.brand a{top:29.5px}}
.nav-wrap{float:left;width:33.33333333%;padding:0 15px;min-height:1px}
.nav-toggle{display:block;float:right;line-height:26px;padding:26px 0;color:var(--on-dark);cursor:pointer}
.nav-toggle .icon{display:inline-block;font-size:22px;line-height:22px}

/* The original opens this with jQuery's .toggle('slow'), which is 600ms of
   swing easing on WIDTH, HEIGHT, OPACITY and the vertical margins together --
   the panel grows out of its top-left corner, it does not just drop down.
   Measured on the original at viewport 501, x pinned at 0 throughout:

     +80ms  w33  h15  op.06  mt1      +400ms  w412 h188 op.82  mt16
     +160ms w112 h51  op.22  mt4      +550ms  w501 h228 op1.0  mt20
     +280ms w258 h117 op.51  mt10

   Reproduced in CSS, so the rebuild still ships no JavaScript. display: is not
   animatable, so the closed state is grid-template-rows:0fr plus width:0 with
   the child clipped; 1fr resolves to the content's exact height, so the slide
   takes the full duration and cannot clip the menu if a page is ever added.
   cubic-bezier(.37,0,.63,1) is sine ease-in-out, which is what jQuery's swing
   is -- plain ease-in-out is a cubic and visibly lags it through the first
   half. visibility carries what display:none was doing for accessibility,
   keeping the links out of the tab order while closed, switched with a 0s
   transition delayed to the end of the close so it does not cut the fade
   short. margin-top animates with the height because a closed menu must
   occupy no space: leaving the 20px would push the page down while closed. */
.mainnav{display:grid;grid-template-rows:0fr;width:0;overflow:hidden;
  opacity:0;visibility:hidden;margin-top:0;background:var(--page-bg);
  transition:grid-template-rows .6s cubic-bezier(.37,0,.63,1),width .6s cubic-bezier(.37,0,.63,1),
             opacity .6s cubic-bezier(.37,0,.63,1),margin-top .6s cubic-bezier(.37,0,.63,1),
             visibility 0s linear .6s}
.mainnav > *{overflow:hidden;min-height:0}
.nav-check:checked ~ .mainnav{grid-template-rows:1fr;width:100%;opacity:1;
  visibility:visible;margin-top:20px;
  transition:grid-template-rows .6s cubic-bezier(.37,0,.63,1),width .6s cubic-bezier(.37,0,.63,1),
             opacity .6s cubic-bezier(.37,0,.63,1),margin-top .6s cubic-bezier(.37,0,.63,1),visibility 0s}
@media(prefers-reduced-motion:reduce){
  .mainnav,.nav-check:checked ~ .mainnav{transition:none}
}
.mainnav .container{padding:0}
.menu a{display:block;padding:15px 0;color:var(--text-strong);text-align:center;
  border-bottom:1px solid var(--menu-divider);font:400 16px/26px Lato,sans-serif}

@media(min-width:768px){
  .brand{width:33.33333333%}
  .nav-wrap{width:66.66666667%}
}
/* the original swaps to the inline desktop menu at 993px, not at the grid breakpoint */
@media(min-width:993px){
  .nav-wrap{height:60px}
  /* display:none also drops it out of the tab order, matching the original's
     hidden responsive-menu button */
  .nav-check,.nav-toggle{display:none}
  /* z-index:3 is not decoration. The original wraps this nav in a
     `.top-header` that is `position:relative;z-index:3`, i.e. a stacking
     context. It never moves anything, but it does decide how Chromium
     rasterises the link text on the Contact page: see the note on .cards. */
  /* Every part of the mobile menu's animated closed state has to be undone
     here or the desktop nav disappears. width:auto is the load-bearing one:
     this element is absolutely positioned with left and right set, and an
     explicit width beats them, so the base rule's width:0 would collapse it. */
  .mainnav{display:block;position:absolute;top:20px;left:0;right:0;margin:0;z-index:3;background:none;
    width:auto;overflow:visible;opacity:1;visibility:visible;transition:none}
  .mainnav > *{overflow:visible}
  .mainnav .container{padding:0}
  /* the leading float reproduces the original grid's sub-pixel accumulation exactly */
  .mainnav .container::before{content:"";float:left;width:33.33333333%;height:1px}
  .navcol{float:left;width:66.66666667%;padding:0 15px}
  .menu{float:right;margin-top:20px}
  .menu li{float:left;height:40px;font-size:14px;line-height:40px;margin-left:40px}
  .menu li:first-child{margin-left:0}
  .menu a{display:inline;padding:0;border:0;color:var(--on-dark);text-align:left;font:700 16px/26px Lato,sans-serif}
  /* DELIBERATE DEPARTURE FROM THE ORIGINAL.
     illdy's Customizer accent colour is #3d3d3d — the same as the header
     background — so on the original, hovering a nav link makes the text
     vanish. That is a bug, not a design, so it is not reproduced.
     Alternatives if this red is not wanted: #ffde00 (the yellow illdy's own
     stylesheet intended before the accent block overrode it), or #cccccc for
     something subtler. Revert to exact-original by setting this to #3d3d3d. */
  .menu li:hover a{color:var(--brand)}
}

.hero{position:relative;z-index:2;padding:130px 0;text-align:center}
.hero h1{margin:0 0 29px;color:var(--on-dark);font:700 80px/84px Poppins,sans-serif}
@media(max-width:768px){.hero h1{font-size:50px;line-height:54px}}
@media(max-width:500px){.hero h1{font-size:40px;line-height:44px}}
.hero--home{height:606px;padding:0}
@media(max-width:768px){.hero--home{height:166px}}
@media(max-width:500px){.hero--home{height:146px}}

/* ---------- bands / grid ---------- */
.band{background:var(--band-bg)}
.row{max-width:1140px;margin:0 auto}
.band--pt50{padding-top:50px}

.col{float:left;width:33.333%;padding:45px}
.col--full{width:100%}
.col--w3386{width:33.86%}
.col--w32804{width:32.804%}
.col--w32719{width:32.719%}
.col--w32807{width:32.807%}
.col--w3447{width:34.47%}
.col--w34913{width:34.913%}
.col--w32362{width:32.362%}

.divider{padding:15px 0}
.divider::after{content:"";display:block;border-top:3px solid var(--divider)}
.divider--thick::after{border-top-width:4px}

/* ---------- services ---------- */
.svc-list{margin:0 0 20px;
  font:700 25px/26px Roboto,sans-serif;letter-spacing:1.5px;text-transform:uppercase}
.svc-list li{display:flex;justify-content:center;text-align:center}
.svc-title{padding-left:19px;color:var(--brand)}
.svc-title--b{color:var(--brand-alt)}
.svc-title--c{color:var(--brand-alt2)}
.svc-body{margin:30px 0;color:var(--on-dark);text-align:center;
  font:400 16px/26px Vidaloka,sans-serif;letter-spacing:.5px}
/* two descriptions in the original are h2s at 29px/1 wrapping a 16px span — kept verbatim */
.svc-body--alt{margin:0 0 20px;padding:0;color:var(--on-dark);text-align:center;letter-spacing:normal;
  font:700 29px/1 Roboto,sans-serif}
.svc-body--alt span{font-size:16px;font-weight:400}

/* ---------- capabilities ---------- */
.cap-heading{color:var(--accent-red);text-align:center;font:600 65px/65px Roboto,sans-serif}
.cap-list{margin:30px 0;color:var(--on-dark);font:400 16px/26px Vidaloka,sans-serif;letter-spacing:.5px}
.imgrow{padding:2px}
.imgrow .row{display:flex}
.imgrow .col{padding:0;float:none;text-align:center}
.imgrow .col--center{padding:10px}
.imgrow .col--pad81{padding-top:81px}
.imgrow .col--pad61{padding-top:61px}

/* ---------- contact ---------- */
.contact-hero{position:relative;
  background:url(img/contact-bg.jpg) no-repeat 0 0;background-size:cover}
.contact-hero::before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;
  background:var(--contact-overlay);opacity:.39}
.hero-inner{position:relative;z-index:1;max-width:681px;min-height:600px;margin:0 auto;
  display:flex;align-items:center}
.hero-box{width:100%;padding:10px}
.contact-hero h2{margin:0 0 20px;color:var(--contact-heading);text-align:center;text-transform:uppercase;
  font:700 59px/59px Raleway,sans-serif;letter-spacing:1px}
.dots{padding:20px 0;line-height:0}
.dots::after{content:"";display:block;width:10%;margin:0 auto;
  border-top:5px dotted rgba(255,255,255,.5)}

/* position:relative is load-bearing, and not for layout — nothing here is
   offset and nothing is positioned against it. Every Elementor section in the
   original is positioned, and on this page that changes how Chromium
   rasterises text, at one specific combination of width and device pixel
   ratio:
     - `.contact-hero` above sets background-attachment:fixed from 1025px up;
     - from DPR 1.5 up Chromium prefers compositing to LCD text, so it gives
       that fixed background its own composited layer (at DPR 1 it declines,
       precisely to keep LCD text);
     - content that overlaps a composited layer is promoted alongside it, but
       only in units that already form paint layers — i.e. positioned elements;
     - and text inside a composited layer is rasterised with grayscale
       antialiasing instead of subpixel/LCD antialiasing.
   Without this declaration the card headings, descriptions and the email
   address keep subpixel antialiasing where the original has grayscale: 9821
   device pixels differ at 1280x844 DPR 2, with no glyph moving. The colour
   fringes are the whole of the difference. */
.cards{padding:60px 0;position:relative}
.cards .row{display:flex;max-width:1140px;margin:0 auto}
.card{width:50%;padding:70px;text-align:center}
.icon-box{margin-bottom:20px}
/* the original's icon sits on a text baseline, leaving 7px of slack below the glyph */
.icon-wrap{margin-bottom:20px;line-height:0;padding-bottom:7px}
/* the original's icon carries Elementor's 0.5s transition, so its focus ring fades in */
/* Width is pinned to 1em because the two engines disagree otherwise: Chromium
   sizes this inline-block from the font, Firefox from the glyph's advance
   (0.786em for fa-phone), which shifts the icon half a pixel. The original
   lands on 60px in both, so pin it. */
.icon-badge{display:inline-block;width:1em;text-align:center;
  font-size:60px;line-height:60px;color:var(--icon-red);transition:all .5s}
.card--mail .icon-badge{color:var(--accent-red)}
/* Positioned, as in the original — this makes the glyph paint above the
   parent's focus ring rather than under it. The glyph is centred the way the
   original centres it: the ::before is taken out of flow and pulled back by
   half its own advance, NOT by text-align on the line box. Centring it the
   other way renders differently, and differently again per engine, because
   the transform here is not inert:
     - Firefox rounds a transformed frame's offset to a whole LAYOUT DEVICE
       pixel — nsLayoutUtils::PostTranslate, called from nsDisplayTransform's
       GetTransform/GetTransformForRendering. It is a box snap folded into the
       transform matrix, which is why an inert rotate(0deg) triggers it too,
       and why it moves BOTH icons regardless of glyph advance. The glyph
       quantiser itself is untouched. This badge is at x=220.5, so on a 1:1
       layout grid the snap moves it half a pixel right. On a finer grid
       (layout.css.devPixelsPerPx=2) 220.5 is already on the grid and nothing
       moves — measured: the icon bands go to 0 there with this rule reverted.
       So this matters on ordinary-density displays, not on HiDPI ones.
     - WebKit does not do that. RenderLayer::updateTransformFromStyle wraps the
       reference box in snapRectToDevicePixelsIfNeeded before applyTransform, so
       the -50% resolves against a snapped width. That moves any glyph whose
       advance is not a whole number of pixels — here the phone but not the
       envelope, whose advance is exactly 1em.
   Two different mechanisms; reproducing the original's construct is what makes
   both match it exactly rather than approximately. Taking the ::before out of
   flow leaves the <i> with no in-flow content, so its 1em box has to be stated
   explicitly, exactly as the original states it.
   See MECHANISM-PROOF.md for the source citations and FIREFOX-0.5PX.md for the
   measurements — noting that the latter describes the snap as being to a whole
   CSS pixel, which is true only because the test harness's emulated device
   pixel ratio never reaches AppUnitsPerDevPixel. */
/* rotate(0deg) is in the original too — post-2.css sets it on the <i> of both
   icon widgets (.elementor-element-5f8b52f and -7b930598). It is not
   decoration and not inert: it makes the frame transformed, which pins the
   Firefox snap above to the same grid the original uses no matter what the
   badge's geometry is. Without it the ::before centring below only agrees with
   the original while left:50% resolves to a whole CSS pixel — true at
   font-size:60px (30px), false at 21/45/59/60.5/61/75px, where the two
   constructs diverge by a whole CSS pixel at half of all sub-pixel positions.
   Reproducing the rule costs nothing and removes that dependency. */
.icon-badge .icon{display:block;position:relative;width:1em;height:1em;
  font-size:60px;line-height:60px;transform:rotate(0deg)}
.icon-badge .icon::before{position:absolute;left:50%;transform:translateX(-50%)}
.card h3{margin:30px 0;color:var(--card-title);text-transform:uppercase;
  font:700 21px/1.4em Roboto,sans-serif;letter-spacing:1.2px}
.card h3 a{color:var(--card-title)}
.card p{margin:0;color:var(--card-text);font:400 15px/1.5em Roboto,sans-serif}
/* the original sets a zero-offset text-shadow here; it still tints the glyph edges */
.card .value{margin:0;color:var(--text-strong);font:700 25px/1 Roboto,sans-serif;text-shadow:0 0 0 rgba(0,0,0,.3)}
.card .value a{color:var(--text-strong)}
/* the phone number is its own widget in the original, so it keeps the body
   line-height rather than the email heading's — which changes how much the
   text strut pads a vertical-align:middle image at narrow widths */
.card .phone{margin:0;text-align:center}

/* ---------- page shell spacing (matches the theme's article margins) ---------- */
main{padding:50px 0 140px;overflow-wrap:break-word}
.cap-band{padding:10px}
.cap-band .divider{margin-bottom:20px}

/* ---------- responsive ---------- */
@media(max-width:1024px){
  .band--pt50,.band--mpt{padding-top:20px}
  .band--mpb{padding-bottom:20px}
  .cards{padding:80px 30px}
  .card{padding:0 30px}
  .card .value{font-size:15px}
  .contact-hero{padding:0 100px}
}
@media(min-width:1025px){
  .contact-hero{background-attachment:fixed}
}
@media(max-width:767px){
  .col--empty{padding:0;min-height:1px}
  .cards .row,.imgrow .row{display:block}
  main{padding-bottom:100px}
  .contact-hero{padding:0 30px}
  .contact-hero h2{font-size:40px;line-height:40px}
  .col{float:none;width:100%}
  .card{float:none;width:100%;padding:0 60px 60px}
  .card--mail{padding:0 60px 30px}
}


/* ---------- print ---------- */
/* The original inherits Bootstrap 3's print block. Reproduced, including the
   appended link URLs. Note this can never pixel-match the wget mirror used as
   the reference: that mirror's hrefs are capture artifacts
   (../index.html@p=43.html), so the text Bootstrap appends differs from what
   the live original would have printed. */
@media print{
  *,*::before,*::after{color:#000!important;text-shadow:none!important;
    background:0 0!important;box-shadow:none!important}
  /* Bootstrap declares underline here, but the original's theme rule
     `a{text-decoration:none}` loads later and wins, so printed links are
     NOT underlined on the original. Matched. */
  a[href]::after{content:" (" attr(href) ")"}
  a[href^="#"]::after,a[href^="javascript:"]::after{content:""}
  /* the original's Customizer rule outranks Bootstrap's background reset, so
     the home logo still prints */
  /* Bootstrap's `background:0 0` shorthand also resets background-size; on the
     original a longhand background-size survives it, so restore both. */
  header.site-header--home{background-image:url(img/logo.png)!important;
    background-size:contain!important}
  img{max-width:100%!important;page-break-inside:avoid}
  h1,h2,h3{page-break-after:avoid}
  h2,h3,p{orphans:3;widows:3}
}
