Compare commits
37 Commits
07e36d33e3
...
f9fe47a414
Author | SHA1 | Date | |
---|---|---|---|
f9fe47a414 | |||
beff5209f8 | |||
5b50aa01c1 | |||
2002f4b913 | |||
58214dc179 | |||
d7e40e0e3d | |||
9b4bb0fd7c | |||
12650be390 | |||
bc7adaf32f | |||
be9848097e | |||
16ebbfa683 | |||
c9eb9376b3 | |||
5f42340b04 | |||
0191350c48 | |||
9d03f68ec6 | |||
a27c7370d6 | |||
72ce996c37 | |||
d08bfbdcc0 | |||
e96c0dc524 | |||
14ec597b85 | |||
b3076efb2b | |||
0987164982 | |||
31105263b5 | |||
5b95796160 | |||
952eccd560 | |||
475eb92d82 | |||
4ebe4f253c | |||
1ac9fdd641 | |||
489326dc47 | |||
faeaf48d9d | |||
efd6b92298 | |||
31fabb7cbd | |||
230f78f338 | |||
393eeafbd6 | |||
7a4cc84a56 | |||
804e5fb712 | |||
a4c77f3872 |
@ -1,13 +1,33 @@
|
||||
+++
|
||||
title = "Jobs"
|
||||
weight = 1
|
||||
template = "page.html"
|
||||
template = "page-custom-footer-design.html"
|
||||
+++
|
||||
|
||||
{% layout_centered_content() %}
|
||||
##### We are looking for talented people to join our team.
|
||||
{% end %}
|
||||
|
||||
{% layout_centered_content(force_left=true, min_width=true) %}
|
||||
|
||||
We are looking for talented people to join our team. If you want to be at the intersection of physics and engineering, collaborate with world-class scientists, and have the freedom to work with cutting-edge open source technology such as embedded Rust, LLVM, and next-generation FPGA tools such as the nMigen language and Yosys - then consider a job at M-Labs.
|
||||
{% layout_centered_content(min_width=true) %}
|
||||
|
||||
If you want to be at the intersection of physics and engineering, collaborate with world-class scientists, and have the freedom to work with cutting-edge open source technology such as embedded Rust, LLVM, and next-generation FPGA tools such as the nMigen language and Yosys - then consider a job at M-Labs.
|
||||
|
||||
{% end %}
|
||||
|
||||
|
||||
{{ layout_photo_style_1(src1="images/IMG_20170818_175543_HDR@2x.png", src2="images/IMG_0027-side@2x.png") }}
|
||||
|
||||
|
||||
{% layout_centered_content(min_width=true) %}
|
||||
<i>The laboratories at NIST and PTB, where some of the main ARTIQ installations are located</i>
|
||||
{% end %}
|
||||
|
||||
|
||||
{{ layout_photo_style_1(src1="images/IMG_0591-side@2x.png", src2="images/IMG_0591@2x.png") }}
|
||||
|
||||
|
||||
{% layout_centered_content(min_width=true) %}
|
||||
|
||||
Our office is located in the center of Hong Kong, a cosmopolitan city with world-class infrastructure, many cultural and social events, and <a href="https://www.discoverhongkong.com/eng/see-do/great-outdoors/hikes/index.jsp" rel="noopener noreferrer" target="_blank">beautiful natural scenery</a>. It has a separate system from mainland China, where, for example, communications are unrestricted, taxes are low, and customs tariffs virtually inexistent. Hong Kong is located next to Shenzhen, a city with <a href="https://www.wired.co.uk/video/shenzhen-full-documentary" rel="noopener noreferrer" target="_blank">a bustling tech scene</a>, and where many of the world's electronic gadgets are designed and manufactured.
|
||||
|
||||
@ -15,6 +35,9 @@ For local applicants, now is your chance to work on top-notch science and techno
|
||||
|
||||
We also accept remote positions, and you may also choose to work at our sister company QUARTIQ GmbH in Berlin-Adlershof, Germany.
|
||||
|
||||
Contact us at jobs@m-****.hk!
|
||||
|
||||
{% end %}
|
||||
|
||||
|
||||
{% layout_centered_content() %}
|
||||
##### Contact us at jobs@m-****.hk!
|
||||
{% end %}
|
||||
|
@ -10,33 +10,33 @@ template = "page.html"
|
||||
<div class="row">
|
||||
|
||||
|
||||
{% layout_card(title="ARTIQ manual") %}
|
||||
{% layout_card(title="ARTIQ manual", sameheight=100) %}
|
||||
<small>Stable version</small>
|
||||
|
||||
<a href="https://m-labs.hk/artiq/manual.pdf" target="_blank">PDF</a> | <a href="https://m-labs.hk/artiq/manual/" target="_blank" rel="noopener noreferrer">HTML</a>
|
||||
{% end %}
|
||||
|
||||
{% layout_card(title="SiPyCo manual") %}
|
||||
{% layout_card(title="SiPyCo manual", sameheight=100) %}
|
||||
<small>Starting with ARTIQ-5, this library replaces <tt>artiq.protocols</tt>.</small>
|
||||
|
||||
<a href="https://m-labs.hk/artiq/sipyco-manual.pdf" target="_blank">PDF</a> | <a href="https://m-labs.hk/artiq/sipyco-manual/" target="_blank" rel="noopener noreferrer">HTML</a>
|
||||
{% end %}
|
||||
|
||||
{% layout_card(title="ARTIQ manual") %}
|
||||
{% layout_card(title="ARTIQ manual", sameheight=100) %}
|
||||
<small>Beta (development) version</small>
|
||||
|
||||
<a href="https://m-labs.hk/artiq/manual-beta.pdf" target="_blank">PDF</a> | <a href="https://m-labs.hk/artiq/manual-beta/" target="_blank" rel="noopener noreferrer">HTML</a>
|
||||
{% end %}
|
||||
|
||||
|
||||
{% layout_card(title="Slideshow") %}
|
||||
{% layout_card(title="Slideshow", sameheight=100) %}
|
||||
<small>The ARTIQ experiment control system</small>
|
||||
|
||||
<a href="/docs/artiq/artiq_overview.pdf" target="_blank" rel="noopener noreferrer">View slides</a>
|
||||
{% end %}
|
||||
|
||||
|
||||
{% layout_card(title="Slideshow") %}
|
||||
{% layout_card(title="Slideshow", sameheight=100) %}
|
||||
<small>Timing control in ARTIQ</small>
|
||||
|
||||
<a href="/docs/artiq/slides_timing.pdf" target="_blank" rel="noopener noreferrer">View slides</a>
|
||||
@ -120,51 +120,51 @@ We welcome inquiries from research groups of all sizes.<br><a href="https://gith
|
||||
|
||||
<div class="row">
|
||||
|
||||
{% layout_card(title="Entangler core") %}
|
||||
{% layout_card(title="Entangler core", sameheight=120) %}
|
||||
<small>A FPGA core written in Migen with ARTIQ interface, for controlling remote quantum entanglement of trapped ions.</small>
|
||||
|
||||
<a href="https://github.com/OxfordIonTrapGroup/entangler-core" target="_blank" rel="noopener noreferrer">Repository</a> | <a href="https://arxiv.org/abs/1911.10841" target="_blank" rel="noopener noreferrer">Paper</a>
|
||||
{% end %}
|
||||
|
||||
|
||||
{% layout_card(title="ndscan") %}
|
||||
{% layout_card(title="ndscan", sameheight=120) %}
|
||||
<small>N-dimensional scans for ARTIQ</small>
|
||||
|
||||
<a href="https://github.com/OxfordIonTrapGroup/ndscan" target="_blank" rel="noopener noreferrer">Repository</a>
|
||||
{% end %}
|
||||
|
||||
|
||||
{% layout_card(title="Oxford routines") %}
|
||||
{% layout_card(title="Oxford routines", sameheight=120) %}
|
||||
<small>Oxford Ion-Trap Group routines</small>
|
||||
|
||||
<a href="https://github.com/OxfordIonTrapGroup/oitg" target="_blank" rel="noopener noreferrer">Repository</a>
|
||||
{% end %}
|
||||
|
||||
{% layout_card(title="Terminal interface") %}
|
||||
{% layout_card(title="Terminal interface", sameheight=120) %}
|
||||
<small>A terminal interface for the Advanced Real-Time Infrastructure for Quantum physics (ARTIQ).</small>
|
||||
|
||||
<a href="https://github.com/chase1635321/ARTIQ" target="_blank" rel="noopener noreferrer">Repository</a>
|
||||
{% end %}
|
||||
|
||||
{% layout_card(title="ARTIQ-suservo") %}
|
||||
{% layout_card(title="ARTIQ-suservo", sameheight=120) %}
|
||||
<small>A set of scripts for the ARTIQ suservo device.</small>
|
||||
|
||||
<a href="https://github.com/chase1635321/ARTIQ-suservo" target="_blank" rel="noopener noreferrer">Repository</a>
|
||||
{% end %}
|
||||
|
||||
{% layout_card(title="nvOS") %}
|
||||
{% layout_card(title="nvOS", sameheight=120) %}
|
||||
<small>A quantum operating system built around ARTIQ and NV centers in diamond.</small>
|
||||
|
||||
<a href="https://github.com/vontell/nvOS" target="_blank" rel="noopener noreferrer">Repository</a>
|
||||
{% end %}
|
||||
|
||||
{% layout_card(title="Haeffner Lab routines") %}
|
||||
{% layout_card(title="Haeffner Lab routines", sameheight=120) %}
|
||||
<small>Haeffner Lab (Berkeley) routines</small>
|
||||
|
||||
<a href="https://github.com/HaeffnerLab/artiq-work-lattice" target="_blank" rel="noopener noreferrer">Repository</a>
|
||||
{% end %}
|
||||
|
||||
{% layout_card(title="WIPM routines") %}
|
||||
{% layout_card(title="WIPM routines", sameheight=120) %}
|
||||
<small>WIPM (CAS Wuhan) routines</small>
|
||||
|
||||
<a href="https://github.com/GuanQunMu/IonTrap-WIPM" target="_blank" rel="noopener noreferrer">Repository</a>
|
||||
|
@ -21,8 +21,7 @@
|
||||
"babel": {
|
||||
"presets": [
|
||||
"@babel/preset-env",
|
||||
"@babel/preset-react",
|
||||
"minify"
|
||||
"@babel/preset-react"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,6 @@ img.kf25 {
|
||||
width: 310px;
|
||||
}
|
||||
|
||||
|
||||
// Small devices (landscape phones, 576px and up)
|
||||
@media (min-width: 576px) {
|
||||
|
||||
@ -217,7 +216,7 @@ img.kf25 {
|
||||
}
|
||||
|
||||
.card-jobs {
|
||||
background: #fff url("../images/jobs@2x.png") no-repeat center right;
|
||||
background: #fff url("../images/jobs-min@2x.png") no-repeat top right;
|
||||
}
|
||||
|
||||
.logos-centered {
|
||||
@ -240,4 +239,15 @@ img.kf25 {
|
||||
|
||||
// Extra large devices (large desktops, 1200px and up)
|
||||
@media (min-width: 1200px) {
|
||||
}
|
||||
|
||||
/*
|
||||
##Device = Low Resolution Tablets, Mobiles (Landscape)
|
||||
##Screen = B/w 481px to 767px
|
||||
*/
|
||||
@media (min-width: 481px) and (max-width: 767px) {
|
||||
|
||||
#root-shop, #root-shop>div {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
562
static/css/order-hardware.css
Normal file
@ -0,0 +1,562 @@
|
||||
.mobileCloseMenu {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 1em 1em 0;
|
||||
}
|
||||
|
||||
.simu-clone {
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.feedback-add-success {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
##Device = Tablets, Ipads (portrait)
|
||||
##Screen = B/w 768px to 1024px
|
||||
*/
|
||||
@media (min-width: 768px) and (max-width: 1080px) {
|
||||
.logo > img {
|
||||
height: 20px;
|
||||
}
|
||||
.navbar {
|
||||
padding-top: 5px !important;
|
||||
padding-bottom: 5px !important;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
#root-shop, #root-shop>div {
|
||||
height: calc(100vh - 50px);
|
||||
}
|
||||
|
||||
#root-shop .productItem {
|
||||
padding: 2rem 1rem 1rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content img {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content .price {
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content h3 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content ul {
|
||||
font-size: .6rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .control {
|
||||
flex-direction: column;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .control > .description,
|
||||
#root-shop .panel .control > .crate-mode {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#root-shop .panel .control > .crate-mode {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price table {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#root-shop .panel {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
#root-shop .mobileBtnDisplaySideMenu,
|
||||
#root-shop .mobileCloseMenu {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#root-shop .mobileBtnDisplaySideMenu button,
|
||||
#root-shop .mobileCloseMenu button {
|
||||
-webkit-appearance: none !important;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
#root-shop table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#root-shop table tr {
|
||||
padding: .8em 0;
|
||||
display: flex !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
/*
|
||||
##Device = Tablets, Ipads (landscape)
|
||||
##Screen = B/w 768px to 1024px
|
||||
*/
|
||||
@media (min-width: 768px) and (max-width: 1080px) and (orientation: landscape) {
|
||||
.logo > img {
|
||||
height: 20px;
|
||||
}
|
||||
.navbar {
|
||||
padding-top: 5px !important;
|
||||
padding-bottom: 5px !important;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
#root-shop, #root-shop>div {
|
||||
height: calc(100vh - 50px);
|
||||
}
|
||||
|
||||
#root-shop .mobileBtnDisplaySideMenu,
|
||||
#root-shop .mobileCloseMenu {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#root-shop .mobileBtnDisplaySideMenu button,
|
||||
#root-shop .mobileCloseMenu button {
|
||||
-webkit-appearance: none !important;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
#root-shop table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#root-shop table tr {
|
||||
padding: .8em 0;
|
||||
display: flex !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price table {
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price tfoot {
|
||||
font-size: .85rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form input[type="submit"] {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
/*
|
||||
##Device = Low Resolution Tablets, Mobiles (Landscape)
|
||||
##Screen = B/w 481px to 767px
|
||||
*/
|
||||
@media (min-width: 481px) and (max-width: 767px) {
|
||||
.feedback-add-success {
|
||||
background-color: green;
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
padding: 1em;
|
||||
z-index: 100000;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 5px 3px;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
font-size: .75em;
|
||||
}
|
||||
/*.sticky-top {
|
||||
position: fixed;
|
||||
}*/
|
||||
.logo > img {
|
||||
height: 20px;
|
||||
}
|
||||
.navbar {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
#root-shop, #root-shop>div {
|
||||
/*height: calc(100vh - 50px);*/
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root-shop .productItem {
|
||||
padding: 1rem .5rem .5rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content img {
|
||||
height: 230px;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content .price {
|
||||
padding: .3rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content h3 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content ul {
|
||||
font-size: .5rem;
|
||||
}
|
||||
|
||||
#root-shop .panel {
|
||||
padding: 1.3rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .control {
|
||||
flex-direction: column;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .control > .description,
|
||||
#root-shop .panel .control > .crate-mode {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#root-shop .panel .control > .crate-mode {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#root-shop .panel h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price table {
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price tfoot {
|
||||
font-size: .85rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form input[type="submit"] {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#root-shop .mobileBtnDisplaySideMenu {
|
||||
background-color: #0d3547;
|
||||
border-bottom-right-radius: 30px;
|
||||
border-top-right-radius: 30px;
|
||||
width: 80px;
|
||||
padding: 5px 0 5px 10px;
|
||||
margin-bottom: -25px;
|
||||
margin-left: -1.3rem;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#root-shop .mobileBtnDisplaySideMenu button,
|
||||
#root-shop .mobileCloseMenu button {
|
||||
-webkit-appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#root-shop table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#root-shop table tr {
|
||||
padding: .8em 0;
|
||||
display: flex !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened {
|
||||
/*transform: translate3d(0, 0, 0);*/
|
||||
transition: left .3s;
|
||||
width: 310px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened + section.main {
|
||||
/*transform: translate3d(310px, 0, 0);*/
|
||||
transition: left .3s;
|
||||
left: 310px;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened + section.main:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside {
|
||||
/*transform: translate3d(-310px, 0px, 0px);*/
|
||||
transition: left .3s;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: -310px;
|
||||
width: 310px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside:after {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside + section.main {
|
||||
/*transform: translate3d(0, 0, 0);*/
|
||||
transition: left .3s;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>section.main {
|
||||
flex: 1;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.should-disappear {
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened {
|
||||
overflow: initial;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened > .backlog-container {
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
/*
|
||||
##Device = Most of the Smartphones Mobiles (Portrait)
|
||||
##Screen = B/w 320px to 479px
|
||||
*/
|
||||
@media (min-width: 320px) and (max-width: 480px) {
|
||||
.feedback-add-success {
|
||||
background-color: green;
|
||||
display: block;
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
padding: 1em;
|
||||
z-index: 100000;
|
||||
color: white;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 5px 3px;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
font-size: .75em;
|
||||
}
|
||||
/*.sticky-top {
|
||||
position: fixed;
|
||||
}*/
|
||||
.logo > img {
|
||||
height: 20px;
|
||||
}
|
||||
.navbar {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
#root-shop, #root-shop>div {
|
||||
height: calc(100vh - 50px);
|
||||
}
|
||||
|
||||
#root-shop .productItem {
|
||||
padding: 1rem .5rem .5rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content .price {
|
||||
padding: .3rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content h3 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened {
|
||||
/*transform: translate3d(0, 0, 0);*/
|
||||
transition: left .3s;
|
||||
width: 310px;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened + section.main {
|
||||
/*transform: translate3d(310px, 0, 0);*/
|
||||
transition: left .3s;
|
||||
left: 310px;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened + section.main:after {
|
||||
content: '';
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, .3);
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside {
|
||||
/*transform: translate3d(-310px, 0px, 0px);*/
|
||||
transition: left .3s;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: -310px;
|
||||
width: 310px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside:after {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside + section.main {
|
||||
/*transform: translate3d(0, 0, 0);*/
|
||||
transition: left .3s;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#root-shop .layout>section.main {
|
||||
flex: 1;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#root-shop .productItem {
|
||||
padding: 2rem 1rem 1rem;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content img {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#root-shop .productItem .content .price {
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
#root-shop .panel {
|
||||
padding: 1.3rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .control {
|
||||
flex-direction: column;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
#root-shop .panel h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .control > .description,
|
||||
#root-shop .panel .control > .crate-mode {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#root-shop .panel .control > .crate-mode {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price table {
|
||||
font-size: .7rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-price tfoot {
|
||||
font-size: .85rem;
|
||||
}
|
||||
|
||||
#root-shop .panel .summary>.summary-form form input[type="submit"] {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#root-shop .mobileBtnDisplaySideMenu {
|
||||
background-color: #0d3547;
|
||||
border-bottom-right-radius: 30px;
|
||||
border-top-right-radius: 30px;
|
||||
width: 80px;
|
||||
padding: 5px 0 5px 10px;
|
||||
margin-bottom: 15px;
|
||||
margin-left: -1.3rem;
|
||||
}
|
||||
|
||||
#root-shop .mobileBtnDisplaySideMenu button,
|
||||
#root-shop .mobileCloseMenu button {
|
||||
-webkit-appearance: none;
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#root-shop table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#root-shop table tr {
|
||||
padding: .8em 0;
|
||||
display: flex !important;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened {
|
||||
overflow: initial;
|
||||
}
|
||||
|
||||
#root-shop .layout>aside.aside.menu-opened > .backlog-container {
|
||||
overflow-y: scroll;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
BIN
static/images/IMG_0027-side.png
Normal file
After Width: | Height: | Size: 146 KiB |
BIN
static/images/IMG_0027-side@2x.png
Normal file
After Width: | Height: | Size: 493 KiB |
BIN
static/images/IMG_0027.png
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
static/images/IMG_0027@2x.png
Normal file
After Width: | Height: | Size: 485 KiB |
BIN
static/images/IMG_0591-side.png
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
static/images/IMG_0591-side@2x.png
Normal file
After Width: | Height: | Size: 443 KiB |
BIN
static/images/IMG_0591.png
Normal file
After Width: | Height: | Size: 145 KiB |
BIN
static/images/IMG_0591@2x.png
Normal file
After Width: | Height: | Size: 490 KiB |
BIN
static/images/IMG_20170818_175543_HDR.png
Normal file
After Width: | Height: | Size: 129 KiB |
BIN
static/images/IMG_20170818_175543_HDR@2x.png
Normal file
After Width: | Height: | Size: 428 KiB |
BIN
static/images/jobs-min.png
Normal file
After Width: | Height: | Size: 72 KiB |
BIN
static/images/jobs-min@2x.png
Normal file
After Width: | Height: | Size: 144 KiB |
7
static/images/shop/icon-close-white.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 22 22">
|
||||
<g id="Group_441" data-name="Group 441" transform="translate(-1251 -346)">
|
||||
<rect id="Rectangle_1020" data-name="Rectangle 1020" width="22" height="22" transform="translate(1251 346)" fill="none"/>
|
||||
<rect id="Rectangle_1021" data-name="Rectangle 1021" width="2.4" height="24" transform="translate(1269.778 347.808) rotate(45)" fill="#fff"/>
|
||||
<rect id="Rectangle_1022" data-name="Rectangle 1022" width="2.4" height="24" transform="translate(1271.192 364.778) rotate(135)" fill="#fff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 594 B |
2
static/js/jquery-3.3.1.min.js
vendored
Normal file
@ -136,6 +136,16 @@ class Layout extends React.PureComponent {
|
||||
return {
|
||||
aside: PropTypes.any,
|
||||
main: PropTypes.any,
|
||||
mobileSideMenuShouldOpen: PropTypes.bool,
|
||||
isMobile: PropTypes.bool,
|
||||
newCardJustAdded: PropTypes.bool,
|
||||
onClickToggleMobileSideMenu: PropTypes.func,
|
||||
};
|
||||
}
|
||||
|
||||
static get defaultProps() {
|
||||
return {
|
||||
mobileSideMenuShouldOpen: false,
|
||||
};
|
||||
}
|
||||
|
||||
@ -143,14 +153,28 @@ class Layout extends React.PureComponent {
|
||||
const {
|
||||
aside,
|
||||
main,
|
||||
mobileSideMenuShouldOpen,
|
||||
isMobile,
|
||||
newCardJustAdded,
|
||||
onClickToggleMobileSideMenu
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className="layout">
|
||||
|
||||
<aside className="aside">{aside}</aside>
|
||||
<aside className={'aside ' + (mobileSideMenuShouldOpen ? 'menu-opened' : '')}>{aside}</aside>
|
||||
|
||||
<section className="main">{main}</section>
|
||||
{mobileSideMenuShouldOpen ? (
|
||||
<section className="main" onClick={onClickToggleMobileSideMenu}>{main}</section>
|
||||
) : (
|
||||
<section className="main">{main}</section>
|
||||
)}
|
||||
|
||||
{isMobile && newCardJustAdded ? (
|
||||
<div className="feedback-add-success">
|
||||
✓ added
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
</div>
|
||||
);
|
||||
@ -182,9 +206,9 @@ class ProductItem extends React.PureComponent {
|
||||
this.handleOnClickAddItem = this.handleOnClickAddItem.bind(this);
|
||||
}
|
||||
|
||||
handleOnClickAddItem(index, e) {
|
||||
handleOnClickAddItem(index, tap, e) {
|
||||
if (this.props.onClickAddItem) {
|
||||
this.props.onClickAddItem(index);
|
||||
this.props.onClickAddItem(index, tap);
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
@ -221,7 +245,7 @@ class ProductItem extends React.PureComponent {
|
||||
|
||||
<div className="content">
|
||||
|
||||
<button onClick={this.handleOnClickAddItem.bind(this, index)}>
|
||||
<button onClick={this.handleOnClickAddItem.bind(this, index, true)}>
|
||||
<img src="/images/shop/icon-add.svg" alt="add" />
|
||||
</button>
|
||||
|
||||
@ -241,7 +265,7 @@ class ProductItem extends React.PureComponent {
|
||||
|
||||
{/* Allows to simulate a clone */}
|
||||
{snapshot.isDragging && (
|
||||
<img className="" src={image} />
|
||||
<img className="simclone" src={image} />
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
@ -263,6 +287,7 @@ class ProductCartItem extends React.PureComponent {
|
||||
|
||||
static get propTypes() {
|
||||
return {
|
||||
isMobile: PropTypes.bool,
|
||||
hovered: PropTypes.bool,
|
||||
index: PropTypes.number.isRequired,
|
||||
model: PropTypes.object.isRequired,
|
||||
@ -326,14 +351,14 @@ class ProductCartItem extends React.PureComponent {
|
||||
}
|
||||
|
||||
handleOnMouseEnterRemoveItem(index, e) {
|
||||
if (this.props.onToggleOverlayRemove) {
|
||||
if (this.props.onToggleOverlayRemove && !this.props.isMobile) {
|
||||
this.props.onToggleOverlayRemove(index, true);
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
handleOnMouseLeaveRemoveItem(index, e) {
|
||||
if (this.props.onToggleOverlayRemove) {
|
||||
if (this.props.onToggleOverlayRemove && !this.props.isMobile) {
|
||||
this.props.onToggleOverlayRemove(index, false);
|
||||
}
|
||||
e.preventDefault();
|
||||
@ -543,6 +568,7 @@ class Cart extends React.PureComponent {
|
||||
|
||||
static get propTypes() {
|
||||
return {
|
||||
isMobile: PropTypes.bool,
|
||||
nbrSlots: PropTypes.number,
|
||||
itemHovered: PropTypes.string,
|
||||
data: PropTypes.object.isRequired,
|
||||
@ -555,6 +581,7 @@ class Cart extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
isMobile,
|
||||
nbrSlots,
|
||||
itemHovered,
|
||||
data,
|
||||
@ -571,6 +598,7 @@ class Cart extends React.PureComponent {
|
||||
}
|
||||
return (
|
||||
<ProductCartItem
|
||||
isMobile={isMobile}
|
||||
hovered={item.id === itemHovered}
|
||||
key={item.id}
|
||||
index={index}
|
||||
@ -722,6 +750,8 @@ class OrderPanel extends React.PureComponent {
|
||||
crate: PropTypes.element,
|
||||
summaryPrice: PropTypes.element,
|
||||
form: PropTypes.element,
|
||||
isMobile: PropTypes.bool,
|
||||
onClickToggleMobileSideMenu: PropTypes.func,
|
||||
};
|
||||
}
|
||||
|
||||
@ -733,6 +763,8 @@ class OrderPanel extends React.PureComponent {
|
||||
crate,
|
||||
summaryPrice,
|
||||
form,
|
||||
isMobile,
|
||||
onClickToggleMobileSideMenu
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
@ -746,6 +778,14 @@ class OrderPanel extends React.PureComponent {
|
||||
{crateMode}
|
||||
</div>
|
||||
|
||||
{isMobile ? (
|
||||
<div className="mobileBtnDisplaySideMenu">
|
||||
<button onClick={onClickToggleMobileSideMenu}>
|
||||
<img src="/images/shop/icon-add.svg" alt="add" />
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{crate}
|
||||
|
||||
<section className="summary">
|
||||
@ -1026,7 +1066,9 @@ class Backlog extends React.PureComponent {
|
||||
currency: PropTypes.string,
|
||||
data: PropTypes.object.isRequired,
|
||||
items: PropTypes.object,
|
||||
isMobile: PropTypes.bool,
|
||||
onClickAddItem: PropTypes.func,
|
||||
onClickToggleMobileSideMenu: PropTypes.func,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1042,6 +1084,8 @@ class Backlog extends React.PureComponent {
|
||||
data,
|
||||
items,
|
||||
onClickAddItem,
|
||||
onClickToggleMobileSideMenu,
|
||||
isMobile,
|
||||
} = this.props;
|
||||
|
||||
const ordered_items = data.itemIds.map(itemId => items[itemId]);
|
||||
@ -1072,6 +1116,14 @@ class Backlog extends React.PureComponent {
|
||||
ref={provided.innerRef}
|
||||
{...provided.droppableProps}>
|
||||
|
||||
{isMobile ? (
|
||||
<div className="mobileCloseMenu">
|
||||
<button onClick={onClickToggleMobileSideMenu}>
|
||||
<img src="/images/shop/icon-close-white.svg" alt="add" />
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{products}
|
||||
|
||||
{provided.placeholder && (
|
||||
@ -1115,6 +1167,9 @@ class Shop extends React.PureComponent {
|
||||
this.handleClickSelectItem = this.handleClickSelectItem.bind(this);
|
||||
this.handleClickSubmit = this.handleClickSubmit.bind(this);
|
||||
this.handleToggleOverlayRemove = this.handleToggleOverlayRemove.bind(this);
|
||||
this.handleClickToggleMobileSideMenu = this.handleClickToggleMobileSideMenu.bind(this);
|
||||
|
||||
this.timer = null;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -1152,6 +1207,18 @@ class Shop extends React.PureComponent {
|
||||
prevState.columns.cart.items,
|
||||
this.state.columns.cart.items);
|
||||
}
|
||||
|
||||
if (this.state.newCardJustAdded) {
|
||||
this.timer = setTimeout(() => {
|
||||
this.setState({
|
||||
newCardJustAdded: false,
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.timer);
|
||||
}
|
||||
|
||||
handleCrateModeChange(mode) {
|
||||
@ -1202,7 +1269,7 @@ class Shop extends React.PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
handleClickAddItem(index) {
|
||||
handleClickAddItem(index, tap) {
|
||||
const source = {
|
||||
droppableId: 'backlog',
|
||||
index: index,
|
||||
@ -1215,8 +1282,8 @@ class Shop extends React.PureComponent {
|
||||
this.handleOnDragEnd({
|
||||
source,
|
||||
destination,
|
||||
draggableId: null,
|
||||
});
|
||||
draggableId: null
|
||||
}, tap);
|
||||
}
|
||||
|
||||
handleToggleItemProgress(index, show) {
|
||||
@ -1331,7 +1398,7 @@ class Shop extends React.PureComponent {
|
||||
a.click();
|
||||
}
|
||||
|
||||
handleOnDragEnd(result) {
|
||||
handleOnDragEnd(result, newAdded) {
|
||||
const {
|
||||
source,
|
||||
destination,
|
||||
@ -1342,6 +1409,7 @@ class Shop extends React.PureComponent {
|
||||
if (source.droppableId === 'cart') {
|
||||
this.setState({
|
||||
...this.state,
|
||||
newCardJustAdded: false,
|
||||
columns: {
|
||||
...this.state.columns,
|
||||
[source.droppableId]: {
|
||||
@ -1363,6 +1431,7 @@ class Shop extends React.PureComponent {
|
||||
case 'backlog':
|
||||
this.setState({
|
||||
...this.state,
|
||||
newCardJustAdded: newAdded ? true : false,
|
||||
columns: {
|
||||
...this.state.columns,
|
||||
[destination.droppableId]: {
|
||||
@ -1382,6 +1451,7 @@ class Shop extends React.PureComponent {
|
||||
case destination.droppableId:
|
||||
this.setState({
|
||||
...this.state,
|
||||
newCardJustAdded: false,
|
||||
columns: {
|
||||
...this.state.columns,
|
||||
[destination.droppableId]: {
|
||||
@ -1401,6 +1471,13 @@ class Shop extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
handleClickToggleMobileSideMenu() {
|
||||
this.setState({
|
||||
...this.state,
|
||||
mobileSideMenuShouldOpen: !this.state.mobileSideMenuShouldOpen,
|
||||
});
|
||||
}
|
||||
|
||||
checkAlerts(prevItems, newItems) {
|
||||
console.log('--- START CHECKING CRATE WARNING ---');
|
||||
|
||||
@ -1485,7 +1562,9 @@ class Shop extends React.PureComponent {
|
||||
}
|
||||
|
||||
if (nbUsedSlot > itemsCloned[idx].nbrSlotMax) {
|
||||
rules[itemsCloned[idx].rules.maxSlot.type] = {...itemsCloned[idx].rules.maxSlot};
|
||||
if (itemsCloned[idx].rules.maxSlot.message) {
|
||||
rules[itemsCloned[idx].rules.maxSlot.type] = {...itemsCloned[idx].rules.maxSlot};
|
||||
}
|
||||
itemsData[idx].warnings.maxSlotWarning = {...itemsCloned[idx].rules.maxSlotWarning};
|
||||
}
|
||||
|
||||
@ -1624,7 +1703,9 @@ class Shop extends React.PureComponent {
|
||||
}
|
||||
|
||||
if (nbUsedSlot > 0) {
|
||||
rules[itemsCloned[idx].rules.maxSlot.type] = {...itemsCloned[idx].rules.maxSlot};
|
||||
if (itemsCloned[idx].rules.maxSlot.message) {
|
||||
rules[itemsCloned[idx].rules.maxSlot.type] = {...itemsCloned[idx].rules.maxSlot};
|
||||
}
|
||||
}
|
||||
if (nbUsedSlot > itemsCloned[idx].nbrSlotMax) {
|
||||
itemsData[idx].warnings.maxSlotWarning = {...itemsCloned[idx].rules.maxSlotWarning};
|
||||
@ -1684,23 +1765,35 @@ class Shop extends React.PureComponent {
|
||||
items,
|
||||
columns,
|
||||
rules,
|
||||
mobileSideMenuShouldOpen,
|
||||
newCardJustAdded,
|
||||
} = this.state;
|
||||
|
||||
const isMobile = window.deviceIsMobile();
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={this.handleOnDragEnd}>
|
||||
|
||||
<Layout
|
||||
className="shop"
|
||||
mobileSideMenuShouldOpen={mobileSideMenuShouldOpen}
|
||||
isMobile={isMobile}
|
||||
newCardJustAdded={newCardJustAdded}
|
||||
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
|
||||
aside={
|
||||
<Backlog
|
||||
currency={currency}
|
||||
items={items}
|
||||
data={columns['backlog']}
|
||||
onClickAddItem={this.handleClickAddItem}>
|
||||
onClickAddItem={this.handleClickAddItem}
|
||||
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
|
||||
isMobile={isMobile}>
|
||||
</Backlog>
|
||||
}
|
||||
main={(
|
||||
<OrderPanel
|
||||
onClickToggleMobileSideMenu={this.handleClickToggleMobileSideMenu}
|
||||
isMobile={isMobile}
|
||||
title="Order hardware"
|
||||
description="
|
||||
Drag and drop the cards you want into the crate below to see how the combination would look like. If you have any issues with this ordering system, or if you need other configurations, email us directly anytime at sales@m-****.hk. The price is estimated and must be confirmed by a quote."
|
||||
@ -1716,6 +1809,7 @@ class Shop extends React.PureComponent {
|
||||
<Cart
|
||||
nbrSlots={crateModeSlots[currentMode]}
|
||||
data={columns['cart']}
|
||||
isMobile={isMobile}
|
||||
itemHovered={currentItemHovered}
|
||||
onToggleProgress={this.handleToggleItemProgress}
|
||||
onToggleWarning={this.handleToggleItemWarning}
|
||||
|
1895
static/js/shop.min.js
vendored
@ -1,5 +1,6 @@
|
||||
const shop_data = {
|
||||
|
||||
mobileSideMenuShouldOpen: false,
|
||||
currentItemHovered: null,
|
||||
currentMode: 'rack',
|
||||
currency: 'USD',
|
||||
@ -358,7 +359,7 @@ const shop_data = {
|
||||
type: 'hd68-max-slot',
|
||||
icon: '/shop/icon-reminder.svg',
|
||||
name: 'HD68-IDC',
|
||||
message: 'HD68-IDC has at most 4 IDC-BNC adapters.',
|
||||
message: null,
|
||||
},
|
||||
maxSlotWarning: {
|
||||
type: 'hd68-max-slot-warning',
|
||||
|
@ -49,11 +49,11 @@
|
||||
|
||||
<!-- HEADER -->
|
||||
|
||||
<div class="container-fluid shadow th sticky-top">
|
||||
<div class="container-fluid container-header shadow th sticky-top">
|
||||
|
||||
<header class="container">
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-th-1 justify-content-center justify-content-between pt-3 pb-3" role="navigation">
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-th-1 justify-content-center justify-content-between pt-md-3 pb-md-3" role="navigation">
|
||||
|
||||
<a class="navbar-brand logo mr-0" href="/">
|
||||
<img src="{{ get_url(path='images/logo@2x.png') }}" height="25" alt="logo">
|
||||
@ -83,9 +83,9 @@
|
||||
<div class="dropdown-menu shadow-none shadow-lg text-left text-lg-left" aria-labelledby="navbarDropdown">
|
||||
{% for tmp_page in subsection.pages %}
|
||||
{% if tmp_page.extra.menu_item and tmp_page.extra.menu_item == "th1" %}
|
||||
<a class="dropdown-item pt-2 pb-2 pt-sm-3 pb-sm-3 mx-4 mt-2 mb-2 mt-sm-3 mb-sm-3 w-auto btn btn-primary btn-inversed {% if current_path == tmp_page.path %}active{% endif %}" href="{{ tmp_page.permalink }}">{{ tmp_page.title }}</a>
|
||||
<a class="dropdown-item pt-2 pb-2 mx-4 mt-2 mb-2 mt-sm-3 mb-sm-3 w-auto btn btn-primary btn-inversed {% if current_path == tmp_page.path %}active{% endif %}" href="{{ tmp_page.permalink }}">{{ tmp_page.title }}</a>
|
||||
{% else %}
|
||||
<a class="dropdown-item pt-2 pb-2 pt-sm-3 pb-sm-3 {% if current_path == tmp_page.path %}active{% endif %}" href="{{ tmp_page.permalink }}">{{ tmp_page.title }}</a>
|
||||
<a class="dropdown-item pt-2 pb-2 {% if current_path == tmp_page.path %}active{% endif %}" href="{{ tmp_page.permalink }}">{{ tmp_page.title }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
@ -157,6 +157,9 @@
|
||||
<small>Copyright © <span id="copyright_year"></span>, M-Labs. All Rights Reserved.</small>
|
||||
</p>
|
||||
|
||||
{% block fcopyright %}
|
||||
{% endblock %}
|
||||
|
||||
</footer>
|
||||
{% endblock footer %}
|
||||
|
||||
@ -179,7 +182,7 @@
|
||||
|
||||
<!-- <script src="{{ get_url(path='js/as.js', cachebust=true) }}"></script> -->
|
||||
|
||||
<script src="{{ get_url(path='js/jquery-3.3.1.slim.min.js', cachebust=true) }}"></script>
|
||||
<script src="{{ get_url(path='js/jquery-3.3.1.min.js', cachebust=true) }}"></script>
|
||||
<script src="{{ get_url(path='js/popper-1.14.7.min.js', cachebust=true) }}"></script>
|
||||
<script src="{{ get_url(path='js/bootstrap-4.3.1.min.js', cachebust=true) }}"></script>
|
||||
|
||||
|
@ -111,12 +111,8 @@
|
||||
<p class="card-text pt-3">
|
||||
We are looking for talented people to join our team. If you want to be at the intersection of physics and engineering, collaborate with world-class scientists, and have the freedom to work with cutting-edge open source technology such as embedded Rust, LLVM, and next-generation FPGA tools such as the nMigen language and Yosys - then consider a job at M-Labs.
|
||||
</p>
|
||||
<p class="card-text pt-3"><small>
|
||||
Our office is located in the center of Hong Kong, a cosmopolitan city with world-class infrastructure, many cultural and social events, and <a href="https://www.discoverhongkong.com/eng/see-do/great-outdoors/hikes/index.jsp" rel="noopener noreferrer" target="_blank">beautiful natural scenery</a>. It has a separate system from mainland China, where, for example, communications are unrestricted, taxes are low, and customs tariffs virtually inexistent. Hong Kong is located next to Shenzhen, a city with <a href="https://www.wired.co.uk/video/shenzhen-full-documentary" rel="noopener noreferrer" target="_blank">a bustling tech scene</a>, and where many of the world's electronic gadgets are designed and manufactured.<br />
|
||||
For local applicants, now is your chance to work on top-notch science and technology projects with partners worldwide, including Oxford University and <a href="https://www.nist.gov/nist-and-nobel/dave-wineland" rel="noopener noreferrer" target="_blank">NIST</a> - in <a href="https://web.archive.org/web/20170114210545/https://www.nature.com/articles/s41570-016-0001" rel="noopener noreferrer" target="_blank">a field whose applications are responsible for 20% of GDP</a>. For international applicants, Hong Kong provides <a href="https://www.immd.gov.hk/eng/services/visas/GEP.html" rel="noopener noreferrer" target="_blank">fast</a>, <a href="https://www.immd.gov.hk/eng/services/fee-tables/index.html" rel="noopener noreferrer" target="_blank">low-cost</a>, and relatively hassle-free employment visa processing.<br />
|
||||
We also accept remote positions, and you may also choose to work at our sister company QUARTIQ GmbH in Berlin-Adlershof, Germany.<br />
|
||||
Contact us at jobs@m-****.hk!
|
||||
</small></p>
|
||||
|
||||
<a href="{{ get_url(path='@/about-us/jobs.md') }}" class="btn btn-primary btn-lg">Find out More</a>
|
||||
|
||||
</div>
|
||||
|
||||
@ -142,3 +138,22 @@
|
||||
</main>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block fcopyright %}
|
||||
|
||||
<div class="container text-center">
|
||||
|
||||
<p class="pb-2 text-center">
|
||||
|
||||
<small><a href="https://commons.wikimedia.org/wiki/File:Intel_2nd_Generation_Core_microprocessor_codenamed_Sandy_Bridge_Wafer.jpg" target="_blank" rel="noopener noreferrer">Intel 2nd Generation Core microprocessor codenamed Sandy Bridge Wafer</a> by <a href="https://www.flickr.com/photos/intelfreepress/" target="_blank" rel="noopener noreferrer">Intel Free Press</a> is licensed under the <a href="https://creativecommons.org/licenses/by-sa/2.0/deed.en" target="_blank" rel="noopener noreferrer">CC BY-SA 2.0</a> license.</small>
|
||||
|
||||
<br />
|
||||
|
||||
<small><a href="https://commons.wikimedia.org/wiki/File:Hong_kong_bruce_lee_statue.jpg" target="_blank" rel="noopener noreferrer">Hong Kong Bruce Lee statue</a> by <a href="https://commons.wikimedia.org/w/index.php?+title=User%3AJohnson_Lau" target="_blank" rel="noopener noreferrer">Johnson Lau</a> is licensed under the <a href="https://creativecommons.org/licenses/by-sa/2.5/deed.en" target="_blank" rel="noopener noreferrer">CC BY-SA 2.5</a> license.</small>
|
||||
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
9
templates/page-custom-footer-design.html
Normal file
@ -0,0 +1,9 @@
|
||||
{% extends 'page.html' %}
|
||||
|
||||
|
||||
{% block outside %}
|
||||
|
||||
<div class="container-fluid hero3 d-flex flex-column justify-content-center">
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
@ -1,6 +1,12 @@
|
||||
{% extends 'section.html' %}
|
||||
|
||||
|
||||
{% block deferred_styles %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" href="{{ get_url(path='css/order-hardware.css', cachebust=true) }}">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block hero %}{% endblock %}
|
||||
|
||||
|
||||
@ -21,9 +27,22 @@
|
||||
(function () {
|
||||
function deviceIsMobile() {
|
||||
// https://coderwall.com/p/i817wa/one-line-function-to-detect-mobile-devices-with-javascript
|
||||
return (typeof window.orientation !== 'undefined') || (navigator.userAgent.indexOf('IEMobile') !== -1);
|
||||
return (
|
||||
(typeof window.orientation !== 'undefined') ||
|
||||
navigator.userAgent.match(/Android/i) ||
|
||||
navigator.userAgent.match(/webOS/i) ||
|
||||
navigator.userAgent.match(/iPhone/i) ||
|
||||
navigator.userAgent.match(/iPad/i) ||
|
||||
navigator.userAgent.match(/iPod/i) ||
|
||||
navigator.userAgent.match(/BlackBerry/i) ||
|
||||
navigator.userAgent.match(/Windows Phone/i) ||
|
||||
(navigator.userAgent.indexOf('IEMobile') !== -1)
|
||||
);
|
||||
};
|
||||
|
||||
window.deviceIsMobile = deviceIsMobile;
|
||||
|
||||
return;
|
||||
if (deviceIsMobile()) {
|
||||
alert('The online crate configuration tool is not available for mobile browsers yet. Please use a desktop computer or email us at sales@m-l****.hk to get a quote.');
|
||||
}
|
||||
|
@ -17,7 +17,9 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{{ body | markdown | safe }}
|
||||
<div {% if sameheight %}style="height: {{ sameheight }}px"{% endif%}>
|
||||
{{ body | markdown | safe }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
19
templates/shortcodes/layout_photo_style_1.html
Normal file
@ -0,0 +1,19 @@
|
||||
<div class="{% if css %}{{ css }}{% else %}row d-flex align-items-center mt-5 mb-5{% endif %}">
|
||||
|
||||
<div class="col-12 col-md-6 mb-3 mb-md-0">
|
||||
|
||||
{% if src1 %}
|
||||
<img class="img-fluid" src="{{ get_url(path=src1) }}">
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-6">
|
||||
|
||||
{% if src2 %}
|
||||
<img class="img-fluid" src="{{ get_url(path=src2) }}">
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|