@charset "UTF-8";
/*
author: Zowie Beha
license: Copyright © 2025 Zowie Beha
*/
/* ===========
CSS Reset
============== */
html {
  box-sizing: border-box;
  font-family: "Rubik";
  font-weight: 500;
}

*, *::before, *::after {
  box-sizing: inherit;
  margin: 0;
  padding: 0;
}

html, body {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
}

body {
  background: white;
}

/* ===========
Sticky header & Footer
============== */
.fluid-layout {
  display: grid;
  grid: auto 1fr auto/1fr;
  /*
      100% instead of 100vw, as 100vw includes the space under a vertical scrollbar.
      and when the page extends onto the vertical scrollbar's area, a horizontal scroll bar appears,
      which we do not want.

      read these sources to fully understand and confirm:
          https://www.freecodecamp.org/news/html-page-width-height/
          https://stackoverflow.com/questions/13569610/vertical-scrollbar-leads-to-horizontal-scrollbar
  */
  width: 100%;
  height: 100vh;
}

/* ===========
Nav bar
============== */
#page-header .nav-list {
  background-color: #1D1B2C;
  border-bottom: 3px solid #cdcdd2;
  height: 3.1rem;
  width: 100%;
  padding-right: 2.3rem;
  display: flex;
  gap: 2.3rem;
  /* Mobile column layout for navbar */
  /* Mobile */
}
@media screen and (max-width: 960px) {
  #page-header .nav-list {
    height: auto;
    flex-direction: column;
    gap: 1rem;
    padding-right: 0;
    /* .nav__items' defined width on mobile will opt out of align-items: stretch. center the 
       items on mobile as a fix. */
    align-items: center;
  }
  #page-header .nav-list .ml-auto {
    margin-left: 0;
  }
}
#page-header .nav-list .nav__item {
  /* center contents horizontally and vertically.
  we could use padding on the paragraph instead. */
  text-align: center;
  /*
   * `list-style-type: none` removes the element from the accessibility tree.
   * ::marker has a limited set of properties. `display` is not included,
   * however `font-size` is available, so we can use that to hide the list item markers.
   */
  /* Mobile nav__item */
}
#page-header .nav-list .nav__item::marker {
  font-size: 0;
}
#page-header .nav-list .nav__item .nav__link {
  /* replace with medium-width rubik font */
  line-height: 100%;
  display: inline-block;
  width: 100%;
  /* increase link click area */
  padding: 1rem 0;
  color: white;
  text-decoration: none;
  transition: 0.2s color ease-out;
}
#page-header .nav-list .nav__item .nav__link:hover {
  color: #b9c4f8;
}
@media screen and (max-width: 960px) {
  #page-header .nav-list .nav__item {
    width: 50%;
  }
}
@media screen and (max-width: 960px) {
  #page-header .nav-list {
    /* simulate padding for top/bottom of nav-list, but make it clickable area */
  }
  #page-header .nav-list .nav__item:first-of-type .nav__link {
    padding-top: 2rem;
  }
  #page-header .nav-list .nav__item:last-of-type .nav__link {
    padding-bottom: 2rem;
  }
}

/* ===========
Main
============== */
#page-content {
  /* A single line where we can use margin-top: auto; */
  /* With grid, we would need an additional div to act as a single item,
  which would let use use margin-top: auto;. More markup. Better than flex?
  maybe ... I just don't like nested divs that serve little purpose.  */
  display: flex;
  flex-direction: column;
  align-items: center;
  align-content: flex-start;
  height: 100%;
}
#page-content .content__subheader {
  display: grid;
  grid: 1fr/1fr auto 1fr;
  align-items: center;
  justify-items: center;
  width: 100%;
  /* Mobile content__subheader */
  grid: auto-flow/1fr;
}
#page-content .content__subheader img.img--headshot {
  width: 7.25rem;
  height: 7.25rem;
  border-radius: 100%;
  border: 3px solid #1D1B2C;
  /* Use document background color for nicer visuals when
  the device progressively downloads chunks of an image */
  background: white;
  /* Hide broken img alt text */
  color: white;
  filter: drop-shadow(0 4px 4.8px rgba(29, 27, 44, 0.5411764706));
  object-fit: cover;
  /* Mobile headshot image */
  margin-top: 0.5rem;
  /* Only applies to non-replaced elements (broken img) */
}
#page-content .content__subheader img.img--headshot::after {
  /* Top padding to have a visual center (not mathematical) */
  /* Left/Right padding to cause broken image text to wrap for readability */
  padding: 0.5rem 0.5rem 0 0.5rem;
  font-size: 0.9rem;
}
#page-content .content__subheader .intro-sequence {
  justify-self: left;
  order: -1;
  margin-left: 3.438rem;
  /* Mobile intro-sequence */
  margin-left: 0;
  justify-self: center;
  order: 0;
}
#page-content .content__subheader .intro-sequence .intro-sequence__name {
  font-size: 2.25em;
  /* max-height of fit-content doesn't work strangely */
  max-height: 1.2em;
  filter: drop-shadow(0 2px 1.65px rgba(0, 0, 0, 0.2431372549));
  margin-top: 1rem;
}
#page-content .content__subheader .intro-sequence .intro-sequence__name span > span:nth-child(1) {
  --i: 1 ;
}
#page-content .content__subheader .intro-sequence .intro-sequence__name span > span:nth-child(2) {
  --i: 2 ;
}
#page-content .content__subheader .intro-sequence .intro-sequence__name span > span:nth-child(3) {
  --i: 3 ;
}
#page-content .content__subheader .intro-sequence .intro-sequence__name span > span:nth-child(n) {
  /* I guess this is needed for translation to work...
  i guess I will need to read the guides again. it has to do with display mode */
  display: inline-block;
  opacity: 0;
  animation: 1.3s calc(var(--i) * 0.15s) slide-down-too-far forwards, 1s 1.15s slide-up-to-zero forwards;
}
#page-content .content__subheader .intro-sequence .intro-sequence__career {
  font-size: 1em;
  /* max-height of fit-content doesn't work strangely */
  max-height: 1.2em;
  filter: drop-shadow(0 2px 4.3px rgba(0, 0, 0, 0.0980392157));
  /* Mobile intro-sequence__career */
  display: flex;
  justify-content: center;
}
#page-content .content__subheader .intro-sequence .intro-sequence__career span > span:nth-child(1) {
  --i: 1 ;
}
#page-content .content__subheader .intro-sequence .intro-sequence__career span > span:nth-child(2) {
  --i: 2 ;
}
#page-content .content__subheader .intro-sequence .intro-sequence__career span > span:nth-child(n) {
  /* I guess this is needed for translation to work...
  i guess I will need to read the guides again. it has to do with display mode */
  display: inline-block;
  opacity: 0;
  animation: 0.8s ease-out calc(var(--i) * 0.2s + 0.9s) web-dev-slide-down forwards;
}
#page-content .content__subheader h1.page-title {
  order: 1;
  filter: drop-shadow(0 2px 1.7px rgba(0, 0, 0, 0.2039215686));
  margin-top: 1rem;
}

/* Only works on non-replaced elements (if an image fails to load) */
img::after {
  content: "Image source not found [404]";
  text-align: center;
  display: block;
  color: black;
  /* Use red color for error  */
  background: white;
  background: rgb(255, 128, 128);
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  /* Put over-top the broken image (broken img icon takes up a lot of height for some reason) */
  position: absolute;
  top: 0;
  left: 0;
}

#page-footer {
  /* space between page-content and page-footer if page-content
     contents fill to touch page-footer's top box face */
  margin-top: 1rem;
  border-top: 2px solid #c4c4c4;
  display: grid;
  grid: 1fr/repeat(3, 1fr);
  align-items: center;
  justify-items: center;
  padding: 0.6rem 0;
  /* Mobile column layout for page-footer */
}
@media screen and (max-width: 960px) {
  #page-footer {
    grid: repeat(3, 1fr)/1fr;
    row-gap: 1em;
  }
}
#page-footer p {
  /* For when the copyright text wraps: */
  text-align: center;
}
@media screen and (max-width: 640px) {
  #page-footer p {
    font-size: 1.1rem;
  }
}
#page-footer a.footer__link {
  color: black;
  text-decoration: underline dashed rgb(170, 170, 170) 1px;
  text-underline-offset: 2px;
  transition: 0.2s color ease-out;
}
#page-footer a.footer__link:hover {
  color: #999d53;
}

#page-content p > a[target=_blank]::after,
#page-footer p > a[target=_blank]::after {
  content: "";
  display: inline-block;
  vertical-align: baseline;
  height: 1em;
  width: 1em;
  background: blue;
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='none'%3E%3Cpath d='m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z'/%3E%3Cpath fill='%23000' d='M11 6a1 1 0 1 1 0 2H5v11h11v-6a1 1 0 1 1 2 0v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2zm9-3a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0V6.414l-8.293 8.293a1 1 0 0 1-1.414-1.414L17.586 5H15a1 1 0 1 1 0-2Z'/%3E%3C/g%3E%3C/svg%3E");
}
#page-content p > a[target=_blank]:visited::after,
#page-footer p > a[target=_blank]:visited::after {
  background: rgb(85, 26, 139);
}

div.hr {
  margin-top: 2rem;
  width: 100%;
  opacity: 3%;
  height: 4px;
  background-color: #1D1B2C;
}

p.last-modified {
  font-size: 0.7rem;
  text-align: center;
  padding-top: 4em;
  /* padding for if page-content fills enough free space to reach last-modified */
  margin-top: auto;
}
@media screen and (max-width: 640px) {
  p.last-modified {
    font-size: 1rem;
  }
}

a:hover .icon__img--hover-effect {
  opacity: 0.8;
}

.icon {
  width: 2.125rem;
  height: 2.125rem;
  /* jquery circle is kind of small. make it a bit larger to 
                     be around the same size as the other icons
                  */
}
.icon img.icon__img {
  width: 2.125rem;
  height: 2.125rem;
  object-fit: cover;
  transition: opacity 0.4s ease-out;
}
.icon img.icon__img[title=jQuery] {
  width: 2.255rem;
  height: 2.255rem;
}

/* why does setting width/height to the same value show the full svg,
                whereas aspect-ratio cuts part of it off? */
.icon.icon--medium {
  width: 2.5rem;
  height: 2.5rem;
}
.icon.icon--medium img.icon__img {
  height: 2.5rem;
  width: 2.5rem;
}

.icon.icon--large {
  height: 3rem;
  width: 3rem;
}
.icon.icon--large img.icon__img {
  height: 3rem;
  width: 3rem;
  object-fit: contain;
}

/* ===========
Keyframes
============== */
@keyframes slide-down-too-far {
  from {
    /* use translate instead of relative w/ top, as the text-align
    property will cause unsmooth animation due to centering? dunno
    maybe also a similar reason when working with flex children? */
    /* https://stackoverflow.com/questions/65995712/css-animation-is-not-smooth-it-is-shaking */
    transform: translate3d(0, -0.55em, 0);
    opacity: 0;
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0.35em, 0);
  }
}
@keyframes slide-up-to-zero {
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}
@keyframes web-dev-slide-down {
  /* use translate instead of relative w/ top, as the text-align
      property will cause unsmooth animation due to centering? dunno
      maybe also a similar reason when working with flex children? */
  /* https://stackoverflow.com/questions/65995712/css-animation-is-not-smooth-it-is-shaking */
  from {
    opacity: 0;
    transform: translate3d(0, -1.5rem, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, -0.2em, 0);
  }
}
.pr-06 {
  padding-right: 0.6rem;
}

.ml-auto {
  margin-left: auto;
}

.mt-05 {
  margin-top: 0.5rem;
}

.text-center {
  text-align: center;
}

.flex {
  display: flex;
}

.justify-center {
  justify-content: center;
}

.g-1rem {
  gap: 1rem;
}

.mt-1rem {
  margin-top: 1rem;
}

.text-center {
  text-align: center;
}

/*# sourceMappingURL=base.css.map */
