merging master

This commit is contained in:
Abhinav Adduri 2017-07-25 09:23:42 -07:00
commit 330da9b258
38 changed files with 1670 additions and 1941 deletions

View file

@ -2,10 +2,10 @@
window.Raven=require("raven-js"),window.Raven.config(window.dsn).install(),window.dsn=void 0;const testPilotGA=require("testpilot-ga");window.analytics=new testPilotGA({an:"Firefox Send",ds:"web",tid:window.trackerId});
},{"raven-js":13,"testpilot-ga":17}],2:[function(require,module,exports){
require("./common");const FileReceiver=require("./fileReceiver"),{notify:notify,findMetric:findMetric,sendEvent:sendEvent}=require("./utils"),bytes=require("bytes"),Storage=require("./storage"),storage=new Storage(localStorage),$=require("jquery");require("jquery-circle-progress");const Raven=window.Raven;$(document).ready(function(){$(".send-new").attr("href",window.location.origin),$(".send-new").click(function(e){e.preventDefault(),sendEvent("recipient","restarted",{cd2:"completed"}).then(()=>{location.href=e.currentTarget.href})}),$(".legal-links a, .social-links a, #dl-firefox").click(function(e){e.preventDefault();const t=findMetric(e.currentTarget.href);sendEvent("recipient","exited",{cd3:t}).then(()=>{location.href=e.currentTarget.href})}),$("#expired-send-new").click(function(){storage.referrer="errored-download"});const e=$("#dl-filename").html(),t=Number($("#dl-bytelength").text()),o=Number($("#dl-ttl").text());$("#dl-progress").circleProgress({value:0,startAngle:-Math.PI/2,fill:"#00C8D7",size:158,animation:{duration:300}}),$("#download-btn").click(function(){storage.totalDownloads+=1;const n=new FileReceiver,r=storage.numFiles;n.on("progress",o=>{window.onunload=function(){storage.referrer="cancelled-download",sendEvent("recipient","download-stopped",{cm1:t,cm5:storage.totalUploads,cm6:r,cm7:storage.totalDownloads,cd2:"cancelled"})},$("#download-page-one").attr("hidden",!0),$("#download-progress").removeAttr("hidden");const a=o[0]/o[1];$("#dl-progress").circleProgress("value",a),$(".percent-number").html(`${Math.floor(100*a)}`),$(".progress-text").text(`${e} (${bytes(o[0],{decimalPlaces:1,fixedDecimals:!0})} of ${bytes(o[1],{decimalPlaces:1})})`),1===a&&(n.removeAllListeners("progress"),document.l10n.formatValues("downloadNotification","downloadFinish").then(e=>{notify(e[0]),$(".title").html(e[1])}),window.onunload=null)});let a;n.on("decrypting",e=>{e?console.log("Decrypting"):(console.log("Done decrypting"),a=Date.now())}),n.on("hashing",e=>{e?console.log("Checking file integrity"):console.log("Integrity check done")});const l=Date.now();sendEvent("recipient","download-started",{cm1:t,cm4:o,cm5:storage.totalUploads,cm6:r,cm7:storage.totalDownloads}),n.download().catch(e=>{sendEvent("recipient","download-stopped",{cm1:t,cm5:storage.totalUploads,cm6:r,cm7:storage.totalDownloads,cd2:"errored",cd6:e}),document.l10n.formatValue("expiredPageHeader").then(e=>{$(".title").text(e)}),$("#download-btn").attr("hidden",!0),$("#expired-img").removeAttr("hidden"),console.log("The file has expired, or has already been deleted.")}).then(([e,o])=>{const n=Date.now(),d=n-l,c=t/((n-a)/1e3);storage.referrer="completed-download",sendEvent("recipient","download-stopped",{cm1:t,cm2:d,cm3:c,cm5:storage.totalUploads,cm6:r,cm7:storage.totalDownloads,cd2:"completed"});const i=new DataView(e),s=new Blob([i]),g=URL.createObjectURL(s),m=document.createElement("a");m.href=g,window.navigator.msSaveBlob?window.navigator.msSaveBlob(s,o):(m.download=o,document.body.appendChild(m),m.click())}).catch(e=>(Raven.captureException(e),Promise.reject(e)))})});
require("./common");const FileReceiver=require("./fileReceiver"),{notify:notify,findMetric:findMetric,gcmCompliant:gcmCompliant,sendEvent:sendEvent}=require("./utils"),bytes=require("bytes"),Storage=require("./storage"),storage=new Storage(localStorage),$=require("jquery");require("jquery-circle-progress");const Raven=window.Raven;$(document).ready(function(){gcmCompliant().catch(e=>{$("#download").attr("hidden",!0),sendEvent("recipient","unsupported",{cd6:e}).then(()=>{location.replace("/unsupported")})}),$(".send-new").attr("href",window.location.origin),$(".send-new").click(function(e){e.preventDefault(),sendEvent("recipient","restarted",{cd2:"completed"}).then(()=>{location.href=e.currentTarget.href})}),$(".legal-links a, .social-links a, #dl-firefox").click(function(e){e.preventDefault();const t=findMetric(e.currentTarget.href);sendEvent("recipient","exited",{cd3:t}).then(()=>{location.href=e.currentTarget.href})});const e=$("#dl-filename").text(),t=Number($("#dl-bytelength").text()),o=Number($("#dl-ttl").text());$("#dl-progress").circleProgress({value:0,startAngle:-Math.PI/2,fill:"#3B9DFF",size:158,animation:{duration:300}}),$("#download-btn").click(function(){storage.totalDownloads+=1;const n=new FileReceiver,r=storage.numFiles;n.on("progress",o=>{window.onunload=function(){storage.referrer="cancelled-download",sendEvent("recipient","download-stopped",{cm1:t,cm5:storage.totalUploads,cm6:r,cm7:storage.totalDownloads,cd2:"cancelled"})},$("#download-page-one").attr("hidden",!0),$("#download-progress").removeAttr("hidden");const n=o[0]/o[1];$("#dl-progress").circleProgress("value",n),$(".percent-number").text(`${Math.floor(100*n)}`),$(".progress-text").text(`${e} (${bytes(o[0],{decimalPlaces:1,fixedDecimals:!0})} of ${bytes(o[1],{decimalPlaces:1})})`)});let a;n.on("decrypting",e=>{e?(n.removeAllListeners("progress"),window.onunload=null,document.l10n.formatValue("decryptingFile").then(e=>{$(".progress-text").text(e)})):(console.log("Done decrypting"),a=Date.now())}),n.on("hashing",e=>{e?document.l10n.formatValue("verifyingFile").then(e=>{$(".progress-text").text(e)}):($(".progress-text").text(" "),document.l10n.formatValues("downloadNotification","downloadFinish").then(e=>{notify(e[0]),$(".title").text(e[1])}))});const d=Date.now();sendEvent("recipient","download-started",{cm1:t,cm4:o,cm5:storage.totalUploads,cm6:r,cm7:storage.totalDownloads}),n.download().catch(e=>{sendEvent("recipient","download-stopped",{cm1:t,cm5:storage.totalUploads,cm6:r,cm7:storage.totalDownloads,cd2:"errored",cd6:e}),document.l10n.formatValue("expiredPageHeader").then(e=>{$(".title").text(e)}),$("#download-btn").attr("hidden",!0),$("#expired-img").removeAttr("hidden"),console.log("The file has expired, or has already been deleted.")}).then(([e,o])=>{const n=Date.now(),l=n-d,c=t/((n-a)/1e3);storage.referrer="completed-download",sendEvent("recipient","download-stopped",{cm1:t,cm2:l,cm3:c,cm5:storage.totalUploads,cm6:r,cm7:storage.totalDownloads,cd2:"completed"});const i=new DataView(e),s=new Blob([i]),m=URL.createObjectURL(s),p=document.createElement("a");p.href=m,window.navigator.msSaveBlob?window.navigator.msSaveBlob(s,o):(p.download=o,document.body.appendChild(p),p.click())}).catch(e=>(Raven.captureException(e),Promise.reject(e)))})});
},{"./common":1,"./fileReceiver":3,"./storage":4,"./utils":5,"bytes":6,"jquery":9,"jquery-circle-progress":8}],3:[function(require,module,exports){
const EventEmitter=require("events"),{hexToArray:hexToArray}=require("./utils");class FileReceiver extends EventEmitter{constructor(){super()}download(){return Promise.all([new Promise((e,t)=>{const r=new XMLHttpRequest;r.onprogress=(e=>{e.lengthComputable&&404!==e.target.status&&this.emit("progress",[e.loaded,e.total])}),r.onload=function(i){if(404===r.status)return void t(new Error("The file has expired, or has already been deleted."));const a=new Blob([this.response]),s=new FileReader;s.onload=function(){const t=JSON.parse(r.getResponseHeader("X-File-Metadata"));e({data:this.result,aad:t.aad,filename:t.filename,iv:t.id})},s.readAsArrayBuffer(a)},r.open("get","/assets"+location.pathname.slice(0,-1),!0),r.responseType="blob",r.send()}),window.crypto.subtle.importKey("jwk",{kty:"oct",k:location.hash.slice(1),alg:"A128GCM",ext:!0},{name:"AES-GCM"},!0,["encrypt","decrypt"])]).then(([e,t])=>(this.emit("decrypting",!0),Promise.all([window.crypto.subtle.decrypt({name:"AES-GCM",iv:hexToArray(e.iv),additionalData:hexToArray(e.aad)},t,e.data).then(e=>(this.emit("decrypting",!1),Promise.resolve(e))),e.filename,hexToArray(e.aad)]))).then(([e,t,r])=>(this.emit("hashing",!0),window.crypto.subtle.digest("SHA-256",e).then(i=>(this.emit("hashing",!1),new Uint8Array(i).toString()===r.toString()?(this.emit("safe",!0),Promise.all([e,decodeURIComponent(t)])):(this.emit("unsafe",!0),Promise.reject())))))}}module.exports=FileReceiver;
const EventEmitter=require("events"),{hexToArray:hexToArray}=require("./utils");class FileReceiver extends EventEmitter{constructor(){super()}download(){return Promise.all([new Promise((e,t)=>{const r=new XMLHttpRequest;r.onprogress=(e=>{e.lengthComputable&&404!==e.target.status&&this.emit("progress",[e.loaded,e.total])}),r.onload=function(a){if(404===r.status)return void t(new Error("The file has expired, or has already been deleted."));const i=new Blob([this.response]),s=new FileReader;s.onload=function(){const t=JSON.parse(r.getResponseHeader("X-File-Metadata"));e({data:this.result,aad:t.aad,filename:t.filename,iv:t.id})},s.readAsArrayBuffer(i)},r.open("get","/assets"+location.pathname.slice(0,-1),!0),r.responseType="blob",r.send()}),window.crypto.subtle.importKey("jwk",{kty:"oct",k:location.hash.slice(1),alg:"A128GCM",ext:!0},{name:"AES-GCM"},!0,["encrypt","decrypt"])]).then(([e,t])=>(this.emit("decrypting",!0),Promise.all([window.crypto.subtle.decrypt({name:"AES-GCM",iv:hexToArray(e.iv),additionalData:hexToArray(e.aad),tagLength:128},t,e.data).then(e=>(this.emit("decrypting",!1),Promise.resolve(e))),e.filename,hexToArray(e.aad)]))).then(([e,t,r])=>(this.emit("hashing",!0),window.crypto.subtle.digest("SHA-256",e).then(a=>(this.emit("hashing",!1),new Uint8Array(a).toString()===r.toString()?(this.emit("safe",!0),Promise.all([e,decodeURIComponent(t)])):(this.emit("unsafe",!0),Promise.reject())))))}}module.exports=FileReceiver;
},{"./utils":5,"events":7}],4:[function(require,module,exports){
const{isFile:isFile}=require("./utils");class Storage{constructor(e){this.engine=e}get totalDownloads(){return Number(this.engine.getItem("totalDownloads"))}set totalDownloads(e){this.engine.setItem("totalDownloads",e)}get totalUploads(){return Number(this.engine.getItem("totalUploads"))}set totalUploads(e){this.engine.setItem("totalUploads",e)}get referrer(){return this.engine.getItem("referrer")}set referrer(e){this.engine.setItem("referrer",e)}get files(){const e=[];for(let t=0;t<this.engine.length;t++){const n=this.engine.key(t);isFile(n)&&e.push(JSON.parse(this.engine.getItem(n)))}return e}get numFiles(){let e=0;for(let t=0;t<this.engine.length;t++){const n=this.engine.key(t);isFile(n)&&(e+=1)}return e}getFileById(e){return this.engine.getItem(e)}has(e){return this.engine.hasOwnProperty(e)}remove(e){this.engine.removeItem(e)}addFile(e,t){this.engine.setItem(e,JSON.stringify(t))}}module.exports=Storage;

View file

@ -1,5 +1,7 @@
// Firefox Send is a brand name and should not be localized.
title = Firefox Send
siteSubtitle = web experiment
siteFeedback = Feedback
uploadPageHeader = Private, Encrypted File Sharing
uploadPageExplainer = Send files through a safe, private, and encrypted link that automatically expires to ensure your stuff does not remain online forever.
uploadPageLearnMore = Learn more
@ -10,6 +12,10 @@ uploadPageBrowseButton = Select a file on your computer
uploadPageMultipleFilesAlert = Uploading multiple files or a folder is currently not supported.
uploadPageBrowseButtonTitle = Upload file
uploadingPageHeader = Uploading Your File
importingFile = Importing...
verifyingFile = Verifying...
encryptingFile = Encrypting...
decryptingFile = Decrypting...
notifyUploadDone = Your upload has finished.
uploadingPageMessage = Once your file uploads you will be able to set expiry options.
uploadingPageCancel = Cancel upload
@ -54,8 +60,8 @@ errorAltText
errorPageHeader = Something went wrong!
errorPageMessage = There has been an error uploading the file.
errorPageLink = Send another file
linkExpiredAlt
.alt = Link expired
fileTooBig = That file is too big to upload. It should be less than { $size }.
linkExpiredAlt.alt = Link expired
expiredPageHeader = This link has expired or never existed in the first place!
notSupportedHeader = Your browser is not supported.
// Firefox Send is a brand name and should not be localized.
@ -67,6 +73,16 @@ copyFileList = Copy URL
expiryFileList = Expires In
deleteFileList = Delete
nevermindButton = Never mind
deleteButtonHover
.title = Delete
copyUrlHover
.title = Copy URL
legalHeader = Terms & Privacy
legalNoticeTestPilot = Firefox Send is currently a Test Pilot experiment, and subject to the Test Pilot <a>Terms of Service</a> and <a>Privacy Notice</a>. You can learn more about this experiment and its data collection <a>here</a>.
legalNoticeMozilla = Use of the Firefox Send website is also subject to Mozillas <a>Websites Privacy Notice</a> and <a>Websites Terms of Use</a>.
deletePopupText = Delete this file?
deletePopupYes = Yes
deletePopupCancel = Cancel
deleteButtonHover
.title = Delete
copyUrlHover

View file

@ -1,7 +1,12 @@
/*** index.html ***/
html {
background: url('resources/send_bg.svg');
font-family: 'SF Pro Text', sans-serif;
font-family: -apple-system,
BlinkMacSystemFont,
'SF Pro Text',
Helvetica,
Arial,
sans-serif;
font-weight: 200;
background-size: 100%;
background-repeat: no-repeat;
@ -10,24 +15,95 @@ html {
}
body {
min-height: 100%;
position: relative;
display: flex;
flex-direction: column;
margin: 0;
min-height: 100vh;
position: relative;
}
.header {
align-items: flex-start;
box-sizing: border-box;
display: flex;
justify-content: space-between;
padding: 31px;
width: 100%;
}
.send-logo {
display: flex;
position: relative;
top: 31px;
left: 31px;
display: inline-block;
align-items: center;
}
.site-title {
color: #3e3d40;
font-size: 32px;
font-weight: 500;
margin: 0;
position: relative;
top: -1px;
}
.site-subtitle {
color: #3e3d40;
font-size: 12px;
margin: 0 8px;
}
.site-subtitle a {
font-weight: bold;
color: #3e3d40;
transition: color 50ms;
}
.send-logo:hover a {
color: #0297f8;
}
.feedback {
background-color: #0297f8;
background-image: url('resources/feedback.svg');
background-position: 4px 6px;
background-repeat: no-repeat;
background-size: 14px;
border-radius: 3px;
border: 1px solid #0297f8;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
color: #fff;
cursor: pointer;
display: block;
float: right;
font-size: 12px;
line-height: 12px;
opacity: 0.9;
padding: 6px 6px 5px 20px;
}
.feedback:hover,
.feedback:focus {
background-color: #0287e8;
}
.feedback:active {
background-color: #0277d8;
}
.all {
padding-top: 10%;
padding-bottom: 51px;
flex: 1;
display: flex;
flex-direction: column;
justify-content: flex-start;
max-width: 630px;
margin: 0 auto;
width: 96%;
}
input, select, textarea, button {
input,
select,
textarea,
button {
font-family: inherit;
}
@ -38,24 +114,26 @@ a {
/** page-one **/
.title {
font-size: 33px;
line-height: 40px;
margin: 20px auto;
text-align: center;
max-width: 520px;
font-family: 'SF Pro Display', sans-serif;
}
.description {
font-size: 15px;
line-height: 23px;
width: 630px;
max-width: 630px;
text-align: center;
margin: 0 auto 60px;
color: #0C0C0D;
color: #0c0c0d;
width: 92%;
}
.upload-window {
border: 1px dashed rgba(0, 148, 251, 0.5);
margin: 0 auto;
width: 640px;
height: 255px;
border-radius: 4px;
display: flex;
@ -63,14 +141,15 @@ a {
align-items: center;
flex-direction: column;
text-align: center;
transition: transform 150ms;
padding: 15px;
}
.upload-window.ondrag {
border: 3px dashed rgba(0, 148, 251, 0.5);
margin: 0 auto;
width: 636px;
height: 251px;
transform: scale(1.05);
transform: scale(1.04);
border-radius: 4.2px;
display: flex;
justify-content: center;
@ -80,7 +159,7 @@ a {
}
.link {
color: #0094FB;
color: #0094fb;
text-decoration: none;
}
@ -92,10 +171,10 @@ a {
}
#browse {
background: #0297F8;
background: #0297f8;
border-radius: 5px;
font-size: 15px;
color: #FFF;
color: #fff;
width: 240px;
height: 44px;
display: flex;
@ -104,12 +183,17 @@ a {
cursor: pointer;
}
#browse:hover {
background-color: #0287e8;
}
input[type="file"] {
display: none;
}
#file-size-msg {
font-size: 12px;
line-height: 16px;
color: #737373;
margin-bottom: 22px;
}
@ -129,9 +213,10 @@ th {
td {
font-size: 15px;
vertical-align: top;
color: #4A4A4A;
color: #4a4a4a;
padding: 17px 19px 0;
line-height: 23px;
position: relative;
}
table {
@ -141,42 +226,44 @@ table {
tbody {
word-wrap: break-word;
word-break: break-all;
}
#uploaded-files {
width: 640px;
margin: 45.3px auto;
table-layout: fixed;
}
.icon-delete, .icon-copy, .icon-check {
.icon-delete,
.icon-copy,
.icon-check {
cursor: pointer;
}
/* Popup container */
.popup {
position: relative;
position: absolute;
display: inline-block;
cursor: pointer;
}
/* The actual popup (appears on top) */
.popup .popuptext {
visibility: hidden;
width: 160px;
background-color: #555;
color: #FFF;
min-width: 115px;
background-color: #fff;
color: #000;
border: 1px solid #0297f8;
text-align: center;
border-radius: 6px;
padding: 8px 0;
border-radius: 5px;
padding: 7px 8px;
position: absolute;
z-index: 1;
bottom: 20px;
left: 50%;
margin-left: -88px;
bottom: 8px;
right: -28px;
transition: opacity 0.5s;
opacity: 0;
outline: 0;
box-shadow: 3px 3px 7px #888;
}
/* Popup arrow */
@ -184,11 +271,11 @@ tbody {
content: "";
position: absolute;
top: 100%;
left: 50%;
right: 30px;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #555 transparent transparent;
border-color: #0297f8 transparent transparent;
}
.popup .show {
@ -196,6 +283,29 @@ tbody {
opacity: 1;
}
.popup-message {
margin-bottom: 4px;
}
.popup-yes {
color: #fff;
background-color: #0297f8;
border-radius: 5px;
padding: 2px 11px;
cursor: pointer;
}
.popup-yes:hover {
background-color: #0287e8;
}
.popup-no {
color: #4a4a4a;
border-radius: 6px;
padding: 3px 5px;
cursor: pointer;
}
/** upload-progress **/
.progress-bar {
margin-top: 3px;
@ -239,14 +349,13 @@ tbody {
}
#cancel-upload {
color: #D70022;
color: #d70022;
cursor: pointer;
text-decoration: underline;
}
/** share-link **/
#share-window {
width: 645px;
margin: 0 auto;
display: flex;
justify-content: center;
@ -262,53 +371,59 @@ tbody {
#copy {
display: flex;
flex-wrap: nowrap;
width: 640px;
}
#copy-text {
align-self: flex-start;
margin-top: 60px;
margin-bottom: 10px;
color: #0C0C0D;
color: #0c0c0d;
}
#link {
width: 480px;
flex: 1;
height: 56px;
border: 1px solid #0297F8;
border: 1px solid #0297f8;
border-radius: 6px 0 0 6px;
font-size: 24px;
color: #737373;
font-family: 'SF Pro Display', sans-serif;
letter-spacing: 0;
line-height: 23px;
padding-left: 5px;
padding-right: 5px;
}
#link:disabled {
border: 1px solid #05A700;
background: #FFF;
border: 1px solid #05a700;
background: #fff;
}
#copy-btn {
width: 165px;
height: 60px;
background: #0297F8;
border: 1px solid #0297F8;
flex: 0 1 165px;
background: #0297f8;
border-radius: 0 6px 6px 0;
border: 1px solid #0297f8;
color: white;
cursor: pointer;
font-size: 15px;
height: 60px;
padding-left: 10px;
padding-right: 10px;
white-space: nowrap;
}
#copy-btn:disabled {
background: #05A700;
border: 1px solid #05A700;
background: #05a700;
border: 1px solid #05a700;
cursor: auto;
}
#delete-file {
width: 176px;
height: 44px;
background: #FFF;
background: #fff;
border: 1px solid rgba(12, 12, 13, 0.3);
border-radius: 5px;
font-size: 15px;
@ -322,7 +437,7 @@ tbody {
font-size: 15px;
margin: auto;
text-align: center;
color: #0094FB;
color: #0094fb;
cursor: pointer;
text-decoration: underline;
}
@ -336,7 +451,8 @@ tbody {
text-align: center;
}
#upload-error[hidden], #unsupported-browser[hidden] {
#upload-error[hidden],
#unsupported-browser[hidden] {
display: none;
}
@ -356,9 +472,8 @@ tbody {
.unsupported-description {
font-size: 13px;
line-height: 23px;
width: 630px;
text-align: center;
color: #7D7D7D;
color: #7d7d7d;
margin: 0 auto 23px;
}
@ -370,14 +485,14 @@ tbody {
margin-bottom: 181px;
width: 260px;
height: 80px;
background: #12BC00;
background: #12bc00;
border-radius: 3px;
cursor: pointer;
border: 0;
box-shadow: 0 5px 3px rgb(234, 234, 234);
font-family: 'Fira Sans';
font-weight: 500;
color: #FFF;
color: #fff;
font-size: 26px;
display: flex;
justify-content: center;
@ -406,15 +521,15 @@ tbody {
margin-top: 20px;
margin-bottom: 30px;
text-align: center;
background: #0297F8;
border: 1px solid #0297F8;
background: #0297f8;
border: 1px solid #0297f8;
border-radius: 5px;
font-weight: 300;
cursor: pointer;
}
#download-btn:disabled {
background: #47B04B;
background: #47b04b;
cursor: auto;
}
@ -434,9 +549,8 @@ tbody {
.expired-description {
font-size: 15px;
line-height: 23px;
width: 630px;
text-align: center;
color: #7D7D7D;
color: #7d7d7d;
margin: 0 auto 23px;
}
@ -460,14 +574,13 @@ tbody {
/* footer */
.footer {
position: absolute;
right: 0;
bottom: 0;
left: 0;
font-size: 15px;
display: flex;
align-items: flex-end;
padding: 10px;
padding: 50px 10px 10px;
}
.mozilla-logo {
@ -495,8 +608,69 @@ tbody {
margin-left: 30px;
}
.github, .twitter {
.github,
.twitter {
width: 32px;
height: 32px;
margin-bottom: -5px;
}
@media (max-device-width: 768px) {
.description {
margin: 0 auto 25px;
}
#copy {
width: 100%;
}
#link {
font-size: 18px;
}
.mozilla-logo {
margin-left: -7px;
}
.legal-links > * {
display: block;
padding: 10px 0;
}
}
@media (max-device-width: 520px) {
.header {
flex-direction: column;
justify-content: flex-start;
}
.feedback {
margin-top: 10px;
}
#copy {
width: 100%;
flex-direction: column;
}
#link {
font-size: 22px;
padding: 15px 10px;
border-radius: 6px 6px 0 0;
}
#copy-btn {
border-radius: 0 0 6px 6px;
flex: 0 1 65px;
}
th {
font-size: 14px;
padding: 0 5px;
}
td {
font-size: 13px;
padding: 17px 5px 0;
}
}

View file

@ -0,0 +1 @@
<svg width="15" height="13" viewBox="0 0 15 13" xmlns="http://www.w3.org/2000/svg"><title>Combined Shape</title><path d="M10.274 9.193a5.957 5.957 0 0 1-2.98.778C4.37 9.97 2 7.963 2 5.485 2 3.008 4.37 1 7.294 1c2.924 0 5.294 2.008 5.294 4.485 0 .843-.274 1.632-.751 2.305l.577 2.21-2.14-.807zm-5.983-2.96a.756.756 0 0 0 .763-.748.756.756 0 0 0-.763-.747.756.756 0 0 0-.764.747c0 .413.342.748.764.748zm3.054 0a.756.756 0 0 0 .764-.748.756.756 0 0 0-.764-.747.756.756 0 0 0-.764.747c0 .413.342.748.764.748zm3.054 0a.756.756 0 0 0 .764-.748.756.756 0 0 0-.764-.747.756.756 0 0 0-.763.747c0 .413.342.748.763.748z" fill="#FFF" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 649 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long