Is it a bad idea to push everything in my home folder to a private repo on GitHub?

And if so, why?

I have two ubuntu 18.04 machines that I use for work. One at home and one in the office. I use git and github a lot already. I make configuration changes to files in my home directory often (eg, .pgpass file for postgres etc) and I want those changes replicated between the machines, without me having to remember to explicitly sync them when I leave each one. Using source control makes sense to me, as I want to be able to rewind changes if I mess something up.

However, I’m worried that if I set up a process to sync everything in my home folder, I might accidentally push files that I shouldn’t (eg passwords). I know that I can tell git to ignore everything except the files I explicitly tell it to stage, but then I would lose the option of having it automatically sync everything. Is there a simple git ignore file pattern that would suit my needs?

I would rather not set up a private repo server as I then have to worry about keeping it running.

What are some real world examples of great unit tests? Links to Github repos welcome

I think the title says it all. I’m learning how to write better unit tests and I think that a great way to do it would be to look at some real, production sofware that has really good unit test written. Can you recommend some examples? The language doesn’t matter.

How do I implement a Change control procedure on an open-source GitHub project?

I’m in need of implementing a Change management system with a Change control board for an open-source project. The only other question about Change management questions on here mention ITIL, which is WAY overboard for an open-source project on GitHub. How do I go about implementing a Change control procedure using GitHub and is there an industry-standard Markdown-friendly Change control procedure template I can copy and paste into my project? I’ve done some research but most of what I’ve found is too heavyweight and corporate. Is there anything wrong with the following Change control procedure I pieced together from articles:

  1. A Change Request ticket shall be added to the Changes project Kanban board by submitting an Issue Ticket that shall include a one-sentence Mission statement for the Title along with Problem, Solution, Cost, and Benefits analyses and if needed further Mission Details that clarify the one-sentence Mission statement.
  2. When enough changes have been proposed and the work schedule allows, the Changes Request tickets shall be prioritized based on the order of importance using a cost-benefit analysis by the Change control board.
  3. If a Change Request has been approved by the Change control board, the Change Request ticket shall be moved into the In Progress Changes kanban board, a Change Response Document shall be created by submitting an Issue ticket for each Change Option with sections for the option’s Proposed Solution, Proposed Timeline, Impacts to the Project, and an Expiration Date for Proposed Changes.
  4. Once a Change option for the Change has been agreed upon by the Change control board, the Change Option ticket shall be renamed a Change ticket and marked Major Change or Minor Change before placing it into the In Progress Changes kanban board and closing competing Change option tickets.
  5. All branches containing changes to files affected by the changes defined in the “Impacts to Projects” section of the Change Response shall be merged with their respective parent branches or deleted until there are no more conflicting changes to the affected files, and the Change Request ticket closed.
  6. A new branch created for the Change ticket shall be created where the change shall be implemented and pass all unit tests.
  7. Finished changes shall be reviewed by the Change control board using a Pull Request, at which time the Change ticket shall be moved into the Reviewing kanban board.
  8. If the Pull Request contains any leftover artifacts from the Change or improper unit test coverage, the request shall be denied, requiring steps 7 and 8 to be repeated as many time as necessary.
  9. After a successful Pull Request, the Change ticket shall be moved into the Done Changes kanban board and closed.

Request changes to a commit message during code review on GitHub

I am trying to teach good engineering practices to my team, and in particular, walking them through the basics of PRs and code reviews on GitHub. One of my team members has sent me a request to review his PR, but has added a commit message without any detail, and so I would like to kick it back to him for a better commit message. There doesn’t seem to be a way to do this directly in GitHub. I could just add a “Request Changes” with a general comment on the commit message and ask him to fix it, but how should I tell him to do this? I know it’s possible to do this as a git commit --amend followed by a git push --force, but the docs also say that this is really bad practice for a commit that’s already been pushed, and I don’t want to teach any bad habits. What’s the best way to fix this?

Organizing Github repository with multiple NPM packages

I have a JavaScript frontend plugin that is on Github. This plugin is also available on NPM. Now I’ve decided to adapt framework wrapper for popular frameworks such as React, Angular and Vue. These will also be available on NPM as separate packages with the corresponding framework suffix. So in the end the NPM packages will look like plugin, plugin-react, plugin-ngx, plugin-vue.

How to organize the GitHub side? There are a bunch of options which have pros and cons:

  • I could open a new repo for each package, so in the end I’ll have 4 repos for essentially one plugin
  • I could simply add new folders to the current repo and keep the framework wrappers there. But if I do this and let’s say I’ve a bug in just the React wrapper, how do I manage the release? On NPM only the version of the React wrapper will increase, but on GitHub I’m forced to update the version of the whole repo and things will get messy (or is there another way I don’t know about?)
  • I could keep the current repo and organize it with different branches, so each branch would contain one wrapper. Here I could also do releases per branch, release versions/tags would match on GitHub and NPM.
  • A completely different possibility I don’t know about.

I have little experience with this kind of stuff and I hope someone has a good advice. Maybe there are even official guidelines for this things, but I couldn’t find any since I’ve struggled to formulate this problem in a Google search.

Если скрыть репозиторий GitHub, бесплатный хостинг GitHub Pages будет работать?

У меня бесплатный хостинг GitHub, через репозиторий, если скрыть репозиторий, хостинг будет работать ?

Unable to parse POM.XML from a Github Maven project in Jenkins Maven job

Getting issue when I build jenkins job. Configured Jenkins Maven Job for GitHub Maven project.

I have added JDK Home and automatic Maven installation in global tool configurations.

16:41:34 Parsing POMs 16:41:34 Established TCP socket on 40351 16:41:34 [GitToJenkinsTest] $ /usr/local/java/jdk1.8.0_201/bin/java clean package -cp /var/lib/jenkins/plugins/maven-plugin/WEB-INF/lib/maven31-agent-1.12.jar:/var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven/boot/plexus-classworlds-2.5.1.jar:/var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven/conf/logging jenkins.maven3.agent.Maven31Main /var/lib/jenkins/tools/hudson.tasks.Maven_MavenInstallation/Maven /var/cache/jenkins/war/WEB-INF/lib/remoting-3.29.jar /var/lib/jenkins/plugins/maven-plugin/WEB-INF/lib/maven31-interceptor-1.12.jar /var/lib/jenkins/plugins/maven-plugin/WEB-INF/lib/maven3-interceptor-commons-1.12.jar 40351 16:41:34 Error: Could not find or load main class clean 16:42:04 ERROR: Failed to launch Maven. Exit code = 1 16:42:04 Finished: FAILURE

What if the code found in github with MIT license was stolen by someone and uploaded there?

What would happen if a piece of code from a proprietary source was uploaded by someone without permission to github with the MIT license and thousands of people have used it. Even if the company who owns the code requests github to drop the repository, what would prevent the endless spread of the code by users believing it to have MIT license.

Github desktop not executing, error Segmentation fault (core dumped) in Ubuntu 16.04 TLS

I have new with Ubuntu, In past I using window’s. I installed the Github-desktop in ubuntu using following commands

sudo snap install github-desktop --beta --classic 

Installed successfully and worked 3 – 4 good but next day when I trying to open github desktop its not executing and I found error

Segmentation fault (core dumped) 

I did not know how to fix it, I have reinstall many times but not working. Can you please let me know who to fix it

Thanks

AJAX and JavaScript: Pulling data from the GitHub API for user repositories

I’m looking for specific feedback on a major design change that I plan on making to my personal website (https://aleksandrhovhannisyan.github.io/).

Currently, the Projects section contains hardcoded HTML. With my current approach, each time I want to add a new project, I have to copy-paste an existing project div and customizing the information. Even worse, some of the information, like the stargazer count, must be updated with new commits each time that information changes. There’s also the issue of adding icons to each project, and they’re not always uniform in dimensions (noob alert).

My alternative approach, which I’ve been working on for a couple days now, is to pull data for my repositories using the GitHub API and AJAX. Don’t worry—I’m not authenticating, so no client credentials have to be exposed.

The code (HTML, CSS, JS) is below. Please note that the JavaScript originally contains other functionality as well, like for the light/dark mode switch and the navbar hamburger icon, and so on. But those functions are not relevant for this code review, so I’ve omitted them to make things easier.

Also, I exceeded my character limit for this post, so I stripped most of the HTML that isn’t relevant.

Below are some specific questions I’m hoping people could answer. However, I am more than open to comments on anything else you notice!

  1. Code style/cleanliness: If it isn’t obvious, I’m sort of new to JavaScript and working with APIs. This “overhaul” is my way of getting my feet wet and learning a bit more. Is there anything that makes the JavaScript difficult to read or understand? Does the fact that I have so many functions make it more difficult to keep track of how data is passed around?

  2. The repos map: Is it okay that I have the global repos map up at the top? Is my approach here okay/understandable? What about the get convenience function I defined: is there a better approach? Again, any feedback is appreciated!

  3. Be honest: Which version of the site’s Projects section do you prefer—the one you see here or the original linked at the top of this post? And for what reason(s)?

Thank you in advance! Here’s the code:

var repos = new Map();  setupRepos(); requestRepoData();   /** Defines all repositories of interest, to be displayed in the Projects section of the page in  * the precise order that they appear here. These serve as filters for when we scour through all   * repositories returned by the GitHub API. Though these are mostly hardcoded, we only have to enter  * the information within this function; the rest of the script is not hardcoded in that respect.  * Notable downside: if the name of the repo changes for whatever reason, it will need to be updated here.  */ function setupRepos() {     addRepo("Scribe-Text-Editor", "Scribe: Text Editor", ["cpp", "qt5", "qtcreator"]);     addRepo("EmbodyGame", "Embody: Game", ["csharp", "unity", "ai"]);     addRepo("aleksandrhovhannisyan.github.io", "Personal Website", ["html5", "css", "javascript"]);     addRepo("Steering-Behaviors", "Steering Behaviors", ["csharp", "unity", "ai"]);     addRepo("MIPS-Linked-List", "ASM Linked List", ["mips", "asm", "qtspim"]);     addRepo('Dimension35', "dim35: Game", ["godot", "networking"]); }   /** Associates the given official name of a repo with an object representing custom data about that repository.  * This hashing/association makes it easier to do lookups later on.  *   * @param {string} officialName - The unique name used to identify this repository on GitHub.  * @param {string} customName - A custom name for the repository, not necessarily the same as its official name.  * @param {string[]} topics - An array of strings denoting the topics that correspond to this repo.  */ function addRepo(officialName, customName, topics) {     // Note 1: We define a custom name here for two reasons: 1) some repo names are quite long, such as my website's,     // and 2) multi-word repos have hyphens instead of spaces on GitHub, so we'd need to replace those (which would be wasteful)      // Note 2: We define the topics here instead of parsing them dynamically because GitHub's API returns the topics     // as a *sorted* array, which means we'll end up displaying undesired tags (since we don't show all of them).     // This approach gives us more control but sacrifices flexibility, since we have to enter topics manually for repos of interest.     repos.set(officialName, { "customName" : customName, "topics" : topics, "card" : null }); }   /** Convenience wrapper for accessing the custom data for a particular repo. Uses the given  * repo's official name (per the GitHub API) as the key into the associated Map.  *   * @param {Object} repo - The JSON-parsed object containing a repository's data.  * @returns {Object} The custom object representing the given repo.  */ function get(repo) {     // Notice how the underlying syntax is messy; the wrapper makes it cleaner when used     return repos.get(repo.name); }   function requestRepoData() {     let request = new XMLHttpRequest();     request.open('GET', 'https://api.github.com/users/AleksandrHovhannisyan/repos', true);     request.onload = parseRepos;     request.send(); }   function parseRepos() {     if (this.status !== 200) return;      let data = JSON.parse(this.response);      // Even though we have to loop over all repos to find the ones we want, doing so is arguably     // much faster (and easier) than making separate API requests for each repo of interest     // Also note that GitHub has a rate limit of 60 requests/hr for unauthenticated IPs     for (let repo of data) {         if (repos.has(repo.name)) {             // We cache the card here instead of publishing it immediately so we can display             // the cards in our own order, since the requests are processed out of order (b/c of async)             get(repo).card = createCardFor(repo);         }     }      publishRepoCards(); }   /** Creates a project card for the given repo. A card consists of a header, description,  * and footer, as well as an invisible link and hidden content to be displayed when the  * card is hovered over.  *   * @param {Object} repo - The JSON-parsed object containing a repository's data.  * @returns {Element} A DOM element representing a project card for the given repo.  */ function createCardFor(repo) {     let card = document.createElement('section');     card.setAttribute('class', 'project');     card.appendChild(headerFor(repo));     card.appendChild(descriptionFor(repo));     card.appendChild(footerFor(repo));     card.appendChild(anchorFor(repo));     card.appendChild(createHoverContent());     return card; }   /**  * @param {Object} repo - The JSON-parsed object containing a repository's data.  * @returns {Element} A header for the given repo, consisting of three key pieces:  * the repo icon, the repo name, and the repo's rating (stargazers).  */ function headerFor(repo) {     var header = document.createElement('header');      var icon = document.createElement('span');     icon.setAttribute('class', 'project-icon');     // The emoji part of the description on GitHub     icon.textContent = repo.description.substring(0, 3);          var h4 = document.createElement('h4');     h4.appendChild(icon);     h4.appendChild(nameLabelFor(repo));          header.appendChild(h4);     header.appendChild(stargazerLabelFor(repo));     return header; }   /**  * @param {Object} repo - The JSON-parsed object containing a repository's data.  * @returns {Element} A label for the name of the given repo.  */ function nameLabelFor(repo) {     var projectName = document.createElement('span');     projectName.textContent = get(repo).customName;     return projectName; }   /**  * @param {Object} repo - The JSON-parsed object containing a repository's data.  * @returns {Element} A label showing the number of stargazers for the given repo.  */ function stargazerLabelFor(repo) {     var projectRating = document.createElement('span');          var starIcon = document.createElement('i');     starIcon.setAttribute('class', 'fas fa-star filled');          var starCount = document.createElement('span');     starCount.textContent = ' ' + repo.stargazers_count;          projectRating.setAttribute('class', 'project-rating');     projectRating.appendChild(starIcon);     projectRating.appendChild(starCount);          return projectRating; }   /**  * @param {Object} repo - The JSON-parsed object containing a repository's data.  * @returns {Element} An element containing the description of the given repo.  */ function descriptionFor(repo) {     var description = document.createElement('p');     description.setAttribute('class', 'description');     // Non-emoji part of the description on GitHub     description.textContent = repo.description.substring(3);     return description; }   /**  * @param {Object} repo - The JSON-parsed object containing a repository's data.  * @returns {Element} A footer for the name of the given repo, consisting of at most  * three paragraphs denoting the topics associated with that repo.  */ function footerFor(repo) {     var footer = document.createElement('footer');     footer.setAttribute('class', 'topics');      const numTopicsToShow = 3;     for(let topic of get(repo).topics) {         let p = document.createElement('p');         p.textContent = topic;         footer.appendChild(p);         if (footer.childElementCount === numTopicsToShow) break;     }      return footer; }   /**  * @param {Object} repo - The JSON-parsed object containing a repository's data.  * @returns {Element} An anchor element whose href is set to the given repo's "real" URL.  */ function anchorFor(repo) {     var anchor = document.createElement('a');     anchor.setAttribute('class', 'container-link');     anchor.setAttribute('href', repo.html_url);     anchor.setAttribute('target', '_blank');     return anchor; }   function createHoverContent() {     var hoverContent = document.createElement('div');     hoverContent.setAttribute('class', 'hover-content');          var boldText = document.createElement('strong');     boldText.textContent = 'View on GitHub';      var externalLinkIcon = document.createElement('i');     externalLinkIcon.setAttribute('class', 'fas fa-external-link-alt');          hoverContent.appendChild(boldText);     hoverContent.appendChild(externalLinkIcon);     return hoverContent; }   function publishRepoCards() {     const projects = document.getElementById('projects');     const placeholder = document.getElementById('project-placeholder');      for (let repo of repos.values()) {         projects.insertBefore(repo.card, placeholder);     } }
/* ============================================     General top-level styling     ============================================ */  * {     box-sizing: border-box; }  :root {     --main-bg-color: white;      --nav-bg-color: rgb(44, 44, 44);     --nav-text-color: rgb(179, 177, 177);     --nav-min-height: 50px;     --topic-label-bg-color: #e7e7e7;      --hr-color: rgba(143, 142, 142, 0.2);      --text-color-normal: black;     --text-color-emphasis: black;     --link-color: rgb(39, 83, 133);      --button-bg-color: rgb(39, 83, 133);     --button-bg-hover-color: rgb(83, 129, 182);     --button-text-color: white;     --button-text-hover-color: white;      --skill-hover-bg-color: whitesmoke;          --project-card-bg-color: rgb(253, 253, 253);     --project-card-shadow: 0px 0px 4px 2px rgba(50, 50, 50, 0.4);     --project-card-shadow-hover: 0px 1px 6px 2px rgba(10, 10, 10, 0.6);     --project-card-margin: 30px;          --form-bg-color: rgb(255, 255, 255);     --form-input-margins: 10px;     --form-max-width: 475px;      --page-center-percentage: 80%;     --global-transition-duration: 0.5s;     --institution-info-border-width: 3px; }  .night {     --main-bg-color: rgb(44, 44, 44);     --nav-bg-color: rgb(10, 10, 10);     --topic-label-bg-color: #222222;          --hr-color: rgba(255, 255, 255, 0.2);      --text-color-normal: rgb(179, 177, 177);     --text-color-emphasis: rgb(202, 202, 202);     --link-color: rgb(202, 183, 143);          --button-bg-color: rgb(90, 90, 66);     --button-bg-hover-color: rgb(141, 141, 114);     --button-text-color: var(--text-color-emphasis);     --button-text-hover-color: rgb(24, 24, 24);       --skill-hover-bg-color: rgb(66, 66, 66);     --project-card-bg-color: rgb(54, 54, 54);     /* The shadows need to be a bit more prominent so they contrast well in dark mode,     hence the larger values for blur and spread */     --project-card-shadow: 0 2px 6px 4px rgba(31, 31, 31, 0.9);     --project-card-shadow-hover: 0px 2px 10px 5px rgba(10, 10, 10, 0.6);     --form-bg-color: var(--skill-hover-bg-color); }  #intro {     margin-bottom: 40px; }  #about-me, #projects, #skills, #education, #contact {         /* So the fixed navbar doesn't cover up any content we scroll to */     margin-top: calc((var(--nav-min-height) + 20px) * -1);     padding-top: calc(var(--nav-min-height) + 20px); }  #about-me, #projects, #skills, #education {     margin-bottom: 120px; }  body {     font-family: Nunito, sans-serif;     color: var(--text-color-normal);     background-color: var(--main-bg-color);     transition: background-color var(--global-transition-duration);          width: var(--page-center-percentage);     margin-left: auto;     margin-right: auto; }  i, h1, h2, h4, strong, em {     color: var(--text-color-emphasis); }  .institution-info h4 {     margin-left: 10px;     font-weight: normal;     color: var(--text-color-normal); }  h1 {     font-size: 2em;     margin-block-start: 0.67em;     margin-block-end: 0.67em; }  h1, h2 {     margin-top: 0; }  a {     color: var(--link-color); }  p {     color: var(--text-color-normal); }  /* Links an entire parent container, but the parent must be set to relative position */ .container-link {     position: absolute;     top: 0;     left: 0;     width: 100%;     height: 100%;     text-decoration: none;     z-index: 1; }   /* ============================================     Buttons, collapsibles, etc.     ============================================ */  /* Note: this is an anchor with a class of button */ .button {     width: 100%;     height: 40px;     line-height: 40px;     text-align: center;     display: block;          margin-bottom: 10px;     margin-right: 15px;     border-radius: 10px;          font-size: 1em;     font-weight: bold;     text-decoration: none; }  .collapsible {     font-family: Nunito, sans-serif;     font-size: 1em;     display: flex;     align-items: center;     border: none;     outline: none;     width: 100%; }  .collapsible span {     text-align: left;     padding-left: 10px;     margin-top: 20px;     margin-bottom: 20px; }  .button, .collapsible {     cursor: pointer;     border: none;     background-color: var(--button-bg-color);     transition: var(--global-transition-duration); }  .button, .button *, .collapsible * {     color: var(--button-text-color); }  .button:hover, .collapsible:hover {     background-color: var(--button-bg-hover-color); }  /* To get rid of Firefox's dotted lines when these are clicked */ .button::-moz-focus-inner, .collapsible::-moz-focus-inner {     border: 0; }  .button:hover, .button:hover *, .collapsible:hover * {     color: var(--button-text-hover-color); }  button:focus {     outline: none; }  .fa-angle-right, .fa-angle-down {     margin-left: 10px;     margin-right: 20px;     font-size: 1em; }  @media only screen and (min-width: 400px) {          .main-buttons {         display: flex;     }      .button {         max-width: 200px;      } }   /* ============================================     Navigation (+ night mode nightmode-switch)     ============================================ */  #topnav .centered-content {     width: var(--page-center-percentage);     margin-left: auto;     margin-right: auto;     height: var(--nav-min-height);     display: flex;     justify-content: space-between;     align-items: center; }  #topnav {     width: 100%;     min-height: var(--nav-min-height);     position: fixed;     left: 0;     right: 100%;     top: 0;     background-color: var(--nav-bg-color);      /* This is to ensure that it always appears above everything. */     z-index: 100; }  #topnav * {     color: var(--nav-text-color); }  .nav-links {     padding: 0;     list-style-type: none;     display: none;     margin-left: 0;     margin-right: 0; }  .nav-links li {     text-align: center;     margin: 20px auto; }  .nav-links a {     text-decoration: none;     vertical-align: middle;     transition: var(--global-transition-duration); }  #topnav .nav-links a:hover {     text-decoration: underline;     color: white; }  .navbar-hamburger {     font-size: 1.5em; }  .nightmode-switch-container, .nightmode-switch-container * {     display: inline-block; }  .nightmode-switch {     width: 40px;     height: 20px;     line-height: 15px;     margin-right: 5px;      background-color: var(--nav-bg-color);     border: 3px solid var(--nav-text-color);     border-radius: 100px;     cursor: pointer;     transition: var(--global-transition-duration); }  .nightmode-switch::before {     content: "";     display: inline-block;     vertical-align: middle;     line-height: normal;      margin-left: 2px;     margin-bottom: 2px;     width: 12px;     height: 10px;          background-color: var(--nav-text-color);     border-radius: 50%;     transition: var(--global-transition-duration); }  .night .nightmode-switch::before {     margin-left: 20px; }  .nav-links.active {     display: block;     background-color: var(--nav-bg-color);     color: var(--nav-text-color);          /* Make the dropdown take up 100% of the viewport width */     position: absolute;     left: 0;     right: 0;     top: 20px; }  @media only screen and (min-width: 820px) {      /* This is the most important part: shows the links next to each other     Note: .nav-links.active accounts for an edge case where you open the hamburger     on a small view and then resize the browser so it's larger.     */     .nav-links, .nav-links.active {         margin: 0;         position: static;         display: flex;         flex-direction: row;         justify-content: flex-end;         align-items: center;         font-size: 1.1em;     }      .nav-links li {         margin: 0;     }      .nav-links a {         margin-left: 40px;         transition: var(--global-transition-duration);     }     .navbar-hamburger {        display: none;     } }  /* ============================================     Page header (intro, about me)     ============================================ */  #page-header {     margin-top: 100px;     display: grid;     column-gap: 50px;     grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }  #main-cta {     margin-bottom: 30px;     font-size: 1.1em; }  /* ============================================     Projects/portfolio cards      ============================================ */  #projects {     display: grid;     column-gap: 50px;     row-gap: 50px;     /* Fill up space as it's made available, with each card being a minimum of 250px */     grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }  /* Don't treat the project header as an item/card, keep it on the top row */ #projects h2 {     grid-row: 1;     grid-column: 1 / -1; }  .project {     /* To ensure that .project-link (see below) is absolute relative to us and not the page */     position: relative;     display: grid;     grid-template-columns: 1;     /* Header, description, footer, respectively */     grid-template-rows: max-content 1fr max-content;     row-gap: 20px; }  /* All project cards except the placeholder get a background and box shadow */ .project:not(#project-placeholder) {     background-color: var(--project-card-bg-color);     box-shadow: var(--project-card-shadow);     border-radius: 5px;     transition: all var(--global-transition-duration); }  /* Apply margins to all project headers except the placeholder's */ .project:not(#project-placeholder) header {     margin-top: var(--project-card-margin);     margin-bottom: 0px;     margin-left: var(--project-card-margin);     margin-right: var(--project-card-margin);      display: grid;     grid-template-areas: "heading heading rating"; }  .project-icon * {     width: 24px;     margin-right: 3px;     display: inline-block;     vertical-align: middle; }  .project h4 {     margin: 0px;     align-self: center;     grid-area: heading; }  .project-rating {     font-size: 0.85em;     justify-self: center;     align-self: center;     grid-area: rating; }  .project .description {     margin-top: 0px;     margin-bottom: 0px;     margin-left: var(--project-card-margin);     margin-right: var(--project-card-margin); }  /* Displayed when a user hovers over a project card */ .hover-content {     font-size: 1.2em;     /* Again, note that .project has position: relative */     position: absolute;     top: 0;     left: 0;     width: 100%;     height: 100%;      /* Center the content for the hover layer */     display: flex;     flex-direction: column;     align-items: center;     justify-content: center;      /* Opacity = 0 means it's hidden by default */     opacity: 0;     background-color: var(--skill-hover-bg-color);     transition: var(--global-transition-duration) ease; }  /* Make it clearer which card is hovered over */ .project:hover:not(#project-placeholder) {     box-shadow: var(--project-card-shadow-hover); }  /* Transition for the hover content changes its opacity */ .project:hover .hover-content {     cursor: pointer;     opacity: 0.92; }  .fa-external-link-alt {     margin-top: 20px; }  .project-name {     color: var(--link-color);     text-decoration: none; }  .topics {     display: flex;     flex-wrap: wrap;     grid-row: 3;      margin-top: 0px;     margin-bottom: var(--project-card-margin);     margin-left: var(--project-card-margin);     margin-right: var(--project-card-margin); }  .topics p {     font-size: 0.9em;     padding: 5px;     margin-top: 10px;     margin-bottom: 0px;     margin-right: 10px;      border-radius: 2px;     background-color: var(--topic-label-bg-color);     box-shadow: 0 0 2px black;     transition: background-color var(--global-transition-duration); }  #project-placeholder {     display: flex;     flex-direction: column;     text-align: center;     justify-content: center; }  .github-cta {     display: inline-block;          font-size: 3em;     margin-top: 20px;      text-decoration: none;     color: black; }  /* ============================================     Skills (responsive columns)     ============================================ */  #skills {     display: grid;     column-gap: 50px;     row-gap: 20px;     grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }  #skills h2 {     grid-row: 1;     grid-column: 1 / -1; }  .skill-category h4 {     margin-bottom: 5px; }  .skill-item {     margin-top: 10px;     display: grid;     column-gap: 10px;     grid-template-columns: 1fr 1fr; }  .skill-item:hover {     background-color: var(--skill-hover-bg-color); }  .skill-name {     grid-column: 1; }  .skill-rating {     grid-column: 2;     display: inline;     text-align: right; }  .fa-star.filled {     color: var(--button-bg-color); }  .fa-star.empty {     color: var(--nav-text-color); }  .night .fa-star.filled {     color: rgb(145, 145, 145); }  .night .fa-star.empty {     color: var(--button-bg-color); }  /* ============================================     Education (institutions, coursework, etc.)     ============================================ */  .institution {     margin-top: 20px; }  /* Course and award container */ .institution-info {     display: grid;     /* Mobile first: only one column. Changes to two columns on bigger screens. See media query below. */     grid-template-columns: 1fr;      /* Will be set to a sufficiently large max-height by corresponding click handler for .collapsible */     max-height: 0px;     transition: max-height var(--global-transition-duration);     overflow: hidden;      border: solid var(--institution-info-border-width) var(--button-bg-color);     border-top: none; }  .institution-info .awards {     /* Only matters on mobile, where the awards are stacked underneath courses */     border-top: solid var(--institution-info-border-width) var(--button-bg-color); }  .institution-info ul {     padding-right: 10px; }  .institution-info p {     padding-left: 10px; }  /* Line up courses and awards side by side on larger screens */ @media only screen and (min-width: 800px) {      .institution-info {         grid-template-rows: 1fr;         grid-template-columns: auto auto;     }      .institution-info .awards {         /* Now that it's lined up to the right of the courses, there's no need for a top border */         border-top: none;         /* But there is for a left border */         border-left: solid var(--institution-info-border-width) var(--button-bg-color);     } }  /* ============================================     Contact form     ============================================ */  #contact {     display: grid;     grid-template-areas: "form"                          "socials";     grid-template-rows: auto;     column-gap: 50px; }  #contact-form {     grid-area: form; }  #social-networks {     grid-area: socials; }  @media only screen and (min-width: 700px) {     #contact {         grid-template-areas: "form form form socials";     } }  form {     margin-bottom: 50px;     margin-top: 30px;     max-width: var(--form-max-width); }  form * {     color: var(--text-color-normal);     font-family: Nunito, sans-serif;     font-size: 1em; }  form input:not([class="button"]), form textarea {     height: 30px;     width: 100%;     margin-bottom: 15px;     padding: 10px;          background-color: var(--form-bg-color);     border: 0px solid;     box-shadow: 0 0 3px 1px rgb(172, 172, 172);     border-radius: 3px;     transition: var(--global-transition-duration); }  form label {     margin-bottom: 5px;     display: block; }  form input:focus, form textarea:focus {     outline: none;     box-shadow: 0 0 5px 2px rgb(155, 155, 155); }  form textarea {     max-width: var(--form-max-width);     min-height: 200px;     transition: height 0s;     transition: background-color var(--global-transition-duration); }  form .button {     max-width: 100%;     width: 100%;     height: 45px; }  /* Yum, honey */ input.honeypot {     display: none; }  /* ============================================     Social networks     ============================================ */  #social-networks {     display: grid;     grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));     grid-template-rows: min-content;     grid-auto-rows: min-content;     row-gap: 50px;     column-gap: 30px;     margin-bottom: 50px; }  #social-networks h3 {     grid-row: 1;     grid-column: 1 / -1; }  .social-network {     /* Position relative because we have an absolutely      positioned .container-link as a child */     position: relative;     display: grid;     grid-template-columns: auto 1fr;     column-gap: 20px; }  .social-network:hover {     cursor: pointer;     background-color: var(--skill-hover-bg-color); }  .social-network .fa-stack {     grid-column: 1;     display: grid; }  .fa-stack i {     align-self: center;     justify-self: center; }  /* Whatever icon is being used as the background one */ .fa-stack-2x {     opacity: 0;     font-size: 1.5em;     color: white; }  .night .fa-stack-2x {     opacity: 1; }  .social-network .network-name {     grid-column: 2;     align-self: center; }  #social-networks .fa-linkedin {     color: #0077B5; }  #social-networks .fa-github {     color: black; }  #social-networks .fa-stack-exchange {     color: #195398; }  #social-networks .fa-address-book {     color: #37A000; }  #page-footer {     position: absolute;     left: 0;     height: 50px;     width: 100%;     background: var(--nav-bg-color);     color: var(--nav-text-color);      display: flex;     justify-content: center;     align-items: center; }
<!DOCTYPE html>  <html lang="en">      <head>         <meta http-equiv="X-UA-Compatible" content="ie=edge">         <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">         <meta name="viewport" content="width=device-width, initial-scale=1.0">         <!-- Nunito font looks amazing :) -->         <link href="https://fonts.googleapis.com/css?family=Nunito&display=swap" rel="stylesheet">         <!-- Font Awesome icons -->         <script src="https://kit.fontawesome.com/7d7dc6ad85.js"></script>         <!-- Custom stylesheet -->         <link rel="stylesheet" href="style.css">         <!-- Favicon -->         <link rel="icon" href="favicon.ico" type='image/x-icon'>         <!-- Preview image (e.g., for LinkedIn or Facebook) -->         <meta property="og:image" content="https://avatars2.githubusercontent.com/u/19352442?s=400&amp;v=4">         <title>Aleksandr Hovhannisyan</title>         <!-- Contact form -->         <meta name="referrer" content="origin">     </head>      <body>          <nav id="topnav">             <div class="centered-content">                 <div class="nightmode-switch-container">                     <div class="nightmode-switch"></div><span>Light mode</span>                 </div>                 <i class="navbar-hamburger fas fa-bars"></i>                 <ul class="nav-links">                     <li><a href="#about-me">About Me</a></li>                     <li><a href="#projects">Projects</a></li>                     <li><a href="#skills">Skills</a></li>                     <li><a href="#education">Education</a></li>                     <li><a href="#contact">Contact</a></li>                 </ul>             </div>         </nav>          <article id="content">                          <section id="projects">                 <h2>Projects &#128193;</h2>                  <aside id="project-placeholder" class="project">                     <header>                         <h4>Want to see more of my work?</h4>                     </header>                     <div>                         <p>Check out my other repos:</p>                         <a class="github-cta" href="https://github.com/AleksandrHovhannisyan?tab=repositories" target="_blank"><i class="fab fa-github"></i></a>                     </div>                 </aside>              </section>          </article>          <!-- jQuery CDN -->         <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>         <!-- Custom javascript -->         <script src="index.js"></script>     </body>  </html>